blob: 2942c28a5a6e99452343a04abd9977efddc14831 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Dianne Hackborn905577f2011-09-07 18:31:28 -0700109import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800111import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.util.PrintWriterPrinter;
113import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700114import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Gravity;
116import android.view.LayoutInflater;
117import android.view.View;
118import android.view.WindowManager;
119import android.view.WindowManagerPolicy;
120
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700121import java.io.BufferedInputStream;
122import java.io.BufferedOutputStream;
123import java.io.DataInputStream;
124import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import java.io.File;
126import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700127import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700129import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200130import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800131import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132import java.io.PrintWriter;
133import java.lang.IllegalStateException;
134import java.lang.ref.WeakReference;
135import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700136import java.util.Collections;
137import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138import java.util.HashMap;
139import java.util.HashSet;
140import java.util.Iterator;
141import java.util.List;
142import java.util.Locale;
143import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700144import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700145import java.util.concurrent.atomic.AtomicBoolean;
146import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700148public final class ActivityManagerService extends ActivityManagerNative
149 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 static final String TAG = "ActivityManager";
151 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400152 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 static final boolean DEBUG_SWITCH = localLOGV || false;
154 static final boolean DEBUG_TASKS = localLOGV || false;
155 static final boolean DEBUG_PAUSE = localLOGV || false;
156 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
157 static final boolean DEBUG_TRANSITION = localLOGV || false;
158 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700159 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700161 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_VISBILITY = localLOGV || false;
163 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700164 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800165 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700167 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700168 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700169 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700170 static final boolean DEBUG_POWER = localLOGV || false;
171 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 static final boolean VALIDATE_TOKENS = false;
173 static final boolean SHOW_ACTIVITY_START_TIME = true;
174
175 // Control over CPU and battery monitoring.
176 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
177 static final boolean MONITOR_CPU_USAGE = true;
178 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
179 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
180 static final boolean MONITOR_THREAD_CPU_USAGE = false;
181
Dianne Hackborn1655be42009-05-08 14:29:01 -0700182 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700183 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700184
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800185 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 // Maximum number of recent tasks that we can remember.
188 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700189
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700190 // Amount of time after a call to stopAppSwitches() during which we will
191 // prevent further untrusted switches from happening.
192 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193
194 // How long we wait for a launched process to attach to the activity manager
195 // before we decide it's never going to come up for real.
196 static final int PROC_START_TIMEOUT = 10*1000;
197
Jeff Brown3f9dd282011-07-08 20:02:19 -0700198 // How long we wait for a launched process to attach to the activity manager
199 // before we decide it's never going to come up for real, when the process was
200 // started with a wrapper for instrumentation (such as Valgrind) because it
201 // could take much longer than usual.
202 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 // How long to wait after going idle before forcing apps to GC.
205 static final int GC_TIMEOUT = 5*1000;
206
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700207 // The minimum amount of time between successive GC requests for a process.
208 static final int GC_MIN_INTERVAL = 60*1000;
209
Dianne Hackborn287952c2010-09-22 22:34:31 -0700210 // The rate at which we check for apps using excessive power -- 15 mins.
211 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
212
213 // The minimum sample duration we will allow before deciding we have
214 // enough data on wake locks to start killing things.
215 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
216
217 // The minimum sample duration we will allow before deciding we have
218 // enough data on CPU usage to start killing things.
219 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 // How long we allow a receiver to run before giving up on it.
222 static final int BROADCAST_TIMEOUT = 10*1000;
223
224 // How long we wait for a service to finish executing.
225 static final int SERVICE_TIMEOUT = 20*1000;
226
227 // How long a service needs to be running until restarting its process
228 // is no longer considered to be a relaunch of the service.
229 static final int SERVICE_RESTART_DURATION = 5*1000;
230
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700231 // How long a service needs to be running until it will start back at
232 // SERVICE_RESTART_DURATION after being killed.
233 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
234
235 // Multiplying factor to increase restart duration time by, for each time
236 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
237 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
238
239 // The minimum amount of time between restarting services that we allow.
240 // That is, when multiple services are restarting, we won't allow each
241 // to restart less than this amount of time from the last one.
242 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 // Maximum amount of time for there to be no activity on a service before
245 // we consider it non-essential and allow its process to go on the
246 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700247 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248
249 // How long we wait until we timeout on key dispatching.
250 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 // How long we wait until we timeout on key dispatching during instrumentation.
253 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
254
Dan Egnor42471dd2010-01-07 17:25:22 -0800255 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256
257 static final String[] EMPTY_STRING_ARRAY = new String[0];
258
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700259 public ActivityStack mMainStack;
260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700262 * Description of a request to start a new activity, which has been held
263 * due to app switches being disabled.
264 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700265 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700266 ActivityRecord r;
267 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700268 Uri[] grantedUriPermissions;
269 int grantedMode;
270 boolean onlyIfNeeded;
271 }
272
273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
274 = new ArrayList<PendingActivityLaunch>();
275
276 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 * List of all active broadcasts that are to be executed immediately
278 * (without waiting for another broadcast to finish). Currently this only
279 * contains broadcasts to registered receivers, to avoid spinning up
280 * a bunch of processes to execute IntentReceiver components.
281 */
282 final ArrayList<BroadcastRecord> mParallelBroadcasts
283 = new ArrayList<BroadcastRecord>();
284
285 /**
286 * List of all active broadcasts that are to be executed one at a time.
287 * The object at the top of the list is the currently activity broadcasts;
288 * those after it are waiting for the top to finish..
289 */
290 final ArrayList<BroadcastRecord> mOrderedBroadcasts
291 = new ArrayList<BroadcastRecord>();
292
293 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800294 * Historical data of past broadcasts, for debugging.
295 */
296 static final int MAX_BROADCAST_HISTORY = 100;
297 final BroadcastRecord[] mBroadcastHistory
298 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
299
300 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 * Set when we current have a BROADCAST_INTENT_MSG in flight.
302 */
303 boolean mBroadcastsScheduled = false;
304
305 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 * Activity we have told the window manager to have key focus.
307 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700308 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700309 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 * List of intents that were used to start the most recent tasks.
311 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700312 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313
314 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700315 * Process management.
316 */
317 final ProcessList mProcessList = new ProcessList();
318
319 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 * All of the applications we currently have running organized by name.
321 * The keys are strings of the application package name (as
322 * returned by the package manager), and the keys are ApplicationRecord
323 * objects.
324 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700325 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326
327 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700328 * The currently running heavy-weight process, if any.
329 */
330 ProcessRecord mHeavyWeightProcess = null;
331
332 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 * The last time that various processes have crashed.
334 */
335 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
336
337 /**
338 * Set of applications that we consider to be bad, and will reject
339 * incoming broadcasts from (which the user has no control over).
340 * Processes are added to this set when they have crashed twice within
341 * a minimum amount of time; they are removed from it when they are
342 * later restarted (hopefully due to some user action). The value is the
343 * time it was added to the list.
344 */
345 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
346
347 /**
348 * All of the processes we currently have running organized by pid.
349 * The keys are the pid running the application.
350 *
351 * <p>NOTE: This object is protected by its own lock, NOT the global
352 * activity manager lock!
353 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700354 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355
356 /**
357 * All of the processes that have been forced to be foreground. The key
358 * is the pid of the caller who requested it (we hold a death
359 * link on it).
360 */
361 abstract class ForegroundToken implements IBinder.DeathRecipient {
362 int pid;
363 IBinder token;
364 }
365 final SparseArray<ForegroundToken> mForegroundProcesses
366 = new SparseArray<ForegroundToken>();
367
368 /**
369 * List of records for processes that someone had tried to start before the
370 * system was ready. We don't start them at that point, but ensure they
371 * are started by the time booting is complete.
372 */
373 final ArrayList<ProcessRecord> mProcessesOnHold
374 = new ArrayList<ProcessRecord>();
375
376 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 * List of persistent applications that are in the process
378 * of being started.
379 */
380 final ArrayList<ProcessRecord> mPersistentStartingProcesses
381 = new ArrayList<ProcessRecord>();
382
383 /**
384 * Processes that are being forcibly torn down.
385 */
386 final ArrayList<ProcessRecord> mRemovedProcesses
387 = new ArrayList<ProcessRecord>();
388
389 /**
390 * List of running applications, sorted by recent usage.
391 * The first entry in the list is the least recently used.
392 * It contains ApplicationRecord objects. This list does NOT include
393 * any persistent application records (since we never want to exit them).
394 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800395 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 = new ArrayList<ProcessRecord>();
397
398 /**
399 * List of processes that should gc as soon as things are idle.
400 */
401 final ArrayList<ProcessRecord> mProcessesToGc
402 = new ArrayList<ProcessRecord>();
403
404 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800405 * This is the process holding what we currently consider to be
406 * the "home" activity.
407 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700408 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800409
410 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400411 * Packages that the user has asked to have run in screen size
412 * compatibility mode instead of filling the screen.
413 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700414 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400415
416 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 * Set of PendingResultRecord objects that are currently active.
418 */
419 final HashSet mPendingResultRecords = new HashSet();
420
421 /**
422 * Set of IntentSenderRecord objects that are currently active.
423 */
424 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
425 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
426
427 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800428 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700429 * already logged DropBox entries for. Guarded by itself. If
430 * something (rogue user app) forces this over
431 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
432 */
433 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
434 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
435
436 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700437 * Strict Mode background batched logging state.
438 *
439 * The string buffer is guarded by itself, and its lock is also
440 * used to determine if another batched write is already
441 * in-flight.
442 */
443 private final StringBuilder mStrictModeBuffer = new StringBuilder();
444
445 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700446 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
447 */
448 private boolean mPendingBroadcastTimeoutMessage;
449
450 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 * Intent broadcast that we have tried to start, but are
452 * waiting for its application's process to be created. We only
453 * need one (instead of a list) because we always process broadcasts
454 * one at a time, so no others can be started while waiting for this
455 * one.
456 */
457 BroadcastRecord mPendingBroadcast = null;
458
459 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700460 * The receiver index that is pending, to restart the broadcast if needed.
461 */
462 int mPendingBroadcastRecvIndex;
463
464 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 * Keeps track of all IIntentReceivers that have been registered for
466 * broadcasts. Hash keys are the receiver IBinder, hash value is
467 * a ReceiverList.
468 */
469 final HashMap mRegisteredReceivers = new HashMap();
470
471 /**
472 * Resolver for broadcast intents to registered receivers.
473 * Holds BroadcastFilter (subclass of IntentFilter).
474 */
475 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
476 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
477 @Override
478 protected boolean allowFilterResult(
479 BroadcastFilter filter, List<BroadcastFilter> dest) {
480 IBinder target = filter.receiverList.receiver.asBinder();
481 for (int i=dest.size()-1; i>=0; i--) {
482 if (dest.get(i).receiverList.receiver.asBinder() == target) {
483 return false;
484 }
485 }
486 return true;
487 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700488
489 @Override
490 protected String packageForFilter(BroadcastFilter filter) {
491 return filter.packageName;
492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 };
494
495 /**
496 * State of all active sticky broadcasts. Keys are the action of the
497 * sticky Intent, values are an ArrayList of all broadcasted intents with
498 * that action (which should usually be one).
499 */
500 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
501 new HashMap<String, ArrayList<Intent>>();
502
503 /**
504 * All currently running services.
505 */
506 final HashMap<ComponentName, ServiceRecord> mServices =
507 new HashMap<ComponentName, ServiceRecord>();
508
509 /**
510 * All currently running services indexed by the Intent used to start them.
511 */
512 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
513 new HashMap<Intent.FilterComparison, ServiceRecord>();
514
515 /**
516 * All currently bound service connections. Keys are the IBinder of
517 * the client's IServiceConnection.
518 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700519 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
520 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521
522 /**
523 * List of services that we have been asked to start,
524 * but haven't yet been able to. It is used to hold start requests
525 * while waiting for their corresponding application thread to get
526 * going.
527 */
528 final ArrayList<ServiceRecord> mPendingServices
529 = new ArrayList<ServiceRecord>();
530
531 /**
532 * List of services that are scheduled to restart following a crash.
533 */
534 final ArrayList<ServiceRecord> mRestartingServices
535 = new ArrayList<ServiceRecord>();
536
537 /**
538 * List of services that are in the process of being stopped.
539 */
540 final ArrayList<ServiceRecord> mStoppingServices
541 = new ArrayList<ServiceRecord>();
542
543 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700544 * Backup/restore process management
545 */
546 String mBackupAppName = null;
547 BackupRecord mBackupTarget = null;
548
549 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 * List of PendingThumbnailsRecord objects of clients who are still
551 * waiting to receive all of the thumbnails for a task.
552 */
553 final ArrayList mPendingThumbnails = new ArrayList();
554
555 /**
556 * List of HistoryRecord objects that have been finished and must
557 * still report back to a pending thumbnail receiver.
558 */
559 final ArrayList mCancelledThumbnails = new ArrayList();
560
561 /**
562 * All of the currently running global content providers. Keys are a
563 * string containing the provider name and values are a
564 * ContentProviderRecord object containing the data about it. Note
565 * that a single provider may be published under multiple names, so
566 * there may be multiple entries here for a single one in mProvidersByClass.
567 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700568 final HashMap<String, ContentProviderRecord> mProvidersByName
569 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570
571 /**
572 * All of the currently running global content providers. Keys are a
573 * string containing the provider's implementation class and values are a
574 * ContentProviderRecord object containing the data about it.
575 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700576 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
577 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578
579 /**
580 * List of content providers who have clients waiting for them. The
581 * application is currently being launched and the provider will be
582 * removed from this list once it is published.
583 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700584 final ArrayList<ContentProviderRecord> mLaunchingProviders
585 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586
587 /**
588 * Global set of specific Uri permissions that have been granted.
589 */
590 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
591 = new SparseArray<HashMap<Uri, UriPermission>>();
592
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800593 CoreSettingsObserver mCoreSettingsObserver;
594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 /**
596 * Thread-local storage used to carry caller permissions over through
597 * indirect content-provider access.
598 * @see #ActivityManagerService.openContentUri()
599 */
600 private class Identity {
601 public int pid;
602 public int uid;
603
604 Identity(int _pid, int _uid) {
605 pid = _pid;
606 uid = _uid;
607 }
608 }
609 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
610
611 /**
612 * All information we have collected about the runtime performance of
613 * any user id that can impact battery performance.
614 */
615 final BatteryStatsService mBatteryStatsService;
616
617 /**
618 * information about component usage
619 */
620 final UsageStatsService mUsageStatsService;
621
622 /**
623 * Current configuration information. HistoryRecord objects are given
624 * a reference to this object to indicate which configuration they are
625 * currently running in, so this object must be kept immutable.
626 */
627 Configuration mConfiguration = new Configuration();
628
629 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800630 * Current sequencing integer of the configuration, for skipping old
631 * configurations.
632 */
633 int mConfigurationSeq = 0;
634
635 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700636 * Hardware-reported OpenGLES version.
637 */
638 final int GL_ES_VERSION;
639
640 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 * List of initialization arguments to pass to all processes when binding applications to them.
642 * For example, references to the commonly used services.
643 */
644 HashMap<String, IBinder> mAppBindArgs;
645
646 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700647 * Temporary to avoid allocations. Protected by main lock.
648 */
649 final StringBuilder mStringBuilder = new StringBuilder(256);
650
651 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 * Used to control how we initialize the service.
653 */
654 boolean mStartRunning = false;
655 ComponentName mTopComponent;
656 String mTopAction;
657 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700658 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 boolean mSystemReady = false;
660 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700661 boolean mWaitingUpdate = false;
662 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700663 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700664 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665
666 Context mContext;
667
668 int mFactoryTest;
669
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700670 boolean mCheckedForSetup;
671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700673 * The time at which we will allow normal application switches again,
674 * after a call to {@link #stopAppSwitches()}.
675 */
676 long mAppSwitchesAllowedTime;
677
678 /**
679 * This is set to true after the first switch after mAppSwitchesAllowedTime
680 * is set; any switches after that will clear the time.
681 */
682 boolean mDidAppSwitch;
683
684 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700685 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700686 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700687 long mLastPowerCheckRealtime;
688
689 /**
690 * Last time (in uptime) at which we checked for power usage.
691 */
692 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700693
694 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 * Set while we are wanting to sleep, to prevent any
696 * activities from being started/resumed.
697 */
698 boolean mSleeping = false;
699
700 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700701 * Set if we are shutting down the system, similar to sleeping.
702 */
703 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704
705 /**
706 * Task identifier that activities are currently being started
707 * in. Incremented each time a new task is created.
708 * todo: Replace this with a TokenSpace class that generates non-repeating
709 * integers that won't wrap.
710 */
711 int mCurTask = 1;
712
713 /**
714 * Current sequence id for oom_adj computation traversal.
715 */
716 int mAdjSeq = 0;
717
718 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700719 * Current sequence id for process LRU updating.
720 */
721 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722
723 /**
724 * System monitoring: number of processes that died since the last
725 * N procs were started.
726 */
727 int[] mProcDeaths = new int[20];
728
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700729 /**
730 * This is set if we had to do a delayed dexopt of an app before launching
731 * it, to increasing the ANR timeouts in that case.
732 */
733 boolean mDidDexOpt;
734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 String mDebugApp = null;
736 boolean mWaitForDebugger = false;
737 boolean mDebugTransient = false;
738 String mOrigDebugApp = null;
739 boolean mOrigWaitForDebugger = false;
740 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700741 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700742 String mProfileApp = null;
743 ProcessRecord mProfileProc = null;
744 String mProfileFile;
745 ParcelFileDescriptor mProfileFd;
746 int mProfileType = 0;
747 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700749 final RemoteCallbackList<IActivityWatcher> mWatchers
750 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700751
752 final RemoteCallbackList<IProcessObserver> mProcessObservers
753 = new RemoteCallbackList<IProcessObserver>();
754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 /**
756 * Callback of last caller to {@link #requestPss}.
757 */
758 Runnable mRequestPssCallback;
759
760 /**
761 * Remaining processes for which we are waiting results from the last
762 * call to {@link #requestPss}.
763 */
764 final ArrayList<ProcessRecord> mRequestPssList
765 = new ArrayList<ProcessRecord>();
766
767 /**
768 * Runtime statistics collection thread. This object's lock is used to
769 * protect all related state.
770 */
771 final Thread mProcessStatsThread;
772
773 /**
774 * Used to collect process stats when showing not responding dialog.
775 * Protected by mProcessStatsThread.
776 */
777 final ProcessStats mProcessStats = new ProcessStats(
778 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700779 final AtomicLong mLastCpuTime = new AtomicLong(0);
780 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 long mLastWriteTime = 0;
783
784 /**
785 * Set to true after the system has finished booting.
786 */
787 boolean mBooted = false;
788
Dianne Hackborn7d608422011-08-07 16:24:18 -0700789 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700790 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791
792 WindowManagerService mWindowManager;
793
794 static ActivityManagerService mSelf;
795 static ActivityThread mSystemThread;
796
797 private final class AppDeathRecipient implements IBinder.DeathRecipient {
798 final ProcessRecord mApp;
799 final int mPid;
800 final IApplicationThread mAppThread;
801
802 AppDeathRecipient(ProcessRecord app, int pid,
803 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800804 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 TAG, "New death recipient " + this
806 + " for thread " + thread.asBinder());
807 mApp = app;
808 mPid = pid;
809 mAppThread = thread;
810 }
811
812 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800813 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 TAG, "Death received in " + this
815 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 synchronized(ActivityManagerService.this) {
817 appDiedLocked(mApp, mPid, mAppThread);
818 }
819 }
820 }
821
822 static final int SHOW_ERROR_MSG = 1;
823 static final int SHOW_NOT_RESPONDING_MSG = 2;
824 static final int SHOW_FACTORY_ERROR_MSG = 3;
825 static final int UPDATE_CONFIGURATION_MSG = 4;
826 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
827 static final int WAIT_FOR_DEBUGGER_MSG = 6;
828 static final int BROADCAST_INTENT_MSG = 7;
829 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 static final int SERVICE_TIMEOUT_MSG = 12;
831 static final int UPDATE_TIME_ZONE = 13;
832 static final int SHOW_UID_ERROR_MSG = 14;
833 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700835 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700836 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800837 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700838 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
839 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700840 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700841 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700842 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700843 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700844 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700845 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
846 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847
848 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700849 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850
851 final Handler mHandler = new Handler() {
852 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800853 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 //}
855
856 public void handleMessage(Message msg) {
857 switch (msg.what) {
858 case SHOW_ERROR_MSG: {
859 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 synchronized (ActivityManagerService.this) {
861 ProcessRecord proc = (ProcessRecord)data.get("app");
862 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800863 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 return;
865 }
866 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700867 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800868 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 d.show();
870 proc.crashDialog = d;
871 } else {
872 // The device is asleep, so just pretend that the user
873 // saw a crash dialog and hit "force quit".
874 res.set(0);
875 }
876 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700877
878 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 } break;
880 case SHOW_NOT_RESPONDING_MSG: {
881 synchronized (ActivityManagerService.this) {
882 HashMap data = (HashMap) msg.obj;
883 ProcessRecord proc = (ProcessRecord)data.get("app");
884 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800885 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 return;
887 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800888
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700889 Intent intent = new Intent("android.intent.action.ANR");
890 if (!mProcessesReady) {
891 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
892 }
893 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800894 null, null, 0, null, null, null,
895 false, false, MY_PID, Process.SYSTEM_UID);
896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700898 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 d.show();
900 proc.anrDialog = d;
901 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700902
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700903 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700905 case SHOW_STRICT_MODE_VIOLATION_MSG: {
906 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
907 synchronized (ActivityManagerService.this) {
908 ProcessRecord proc = (ProcessRecord) data.get("app");
909 if (proc == null) {
910 Slog.e(TAG, "App not found when showing strict mode dialog.");
911 break;
912 }
913 if (proc.crashDialog != null) {
914 Slog.e(TAG, "App already has strict mode dialog: " + proc);
915 return;
916 }
917 AppErrorResult res = (AppErrorResult) data.get("result");
918 if (!mSleeping && !mShuttingDown) {
919 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
920 d.show();
921 proc.crashDialog = d;
922 } else {
923 // The device is asleep, so just pretend that the user
924 // saw a crash dialog and hit "force quit".
925 res.set(0);
926 }
927 }
928 ensureBootCompleted();
929 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 case SHOW_FACTORY_ERROR_MSG: {
931 Dialog d = new FactoryErrorDialog(
932 mContext, msg.getData().getCharSequence("msg"));
933 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700934 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 } break;
936 case UPDATE_CONFIGURATION_MSG: {
937 final ContentResolver resolver = mContext.getContentResolver();
938 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
939 } break;
940 case GC_BACKGROUND_PROCESSES_MSG: {
941 synchronized (ActivityManagerService.this) {
942 performAppGcsIfAppropriateLocked();
943 }
944 } break;
945 case WAIT_FOR_DEBUGGER_MSG: {
946 synchronized (ActivityManagerService.this) {
947 ProcessRecord app = (ProcessRecord)msg.obj;
948 if (msg.arg1 != 0) {
949 if (!app.waitedForDebugger) {
950 Dialog d = new AppWaitingForDebuggerDialog(
951 ActivityManagerService.this,
952 mContext, app);
953 app.waitDialog = d;
954 app.waitedForDebugger = true;
955 d.show();
956 }
957 } else {
958 if (app.waitDialog != null) {
959 app.waitDialog.dismiss();
960 app.waitDialog = null;
961 }
962 }
963 }
964 } break;
965 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800966 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 TAG, "Received BROADCAST_INTENT_MSG");
968 processNextBroadcast(true);
969 } break;
970 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700971 synchronized (ActivityManagerService.this) {
972 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700976 if (mDidDexOpt) {
977 mDidDexOpt = false;
978 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
979 nmsg.obj = msg.obj;
980 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
981 return;
982 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 serviceTimeout((ProcessRecord)msg.obj);
984 } break;
985 case UPDATE_TIME_ZONE: {
986 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800987 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
988 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 if (r.thread != null) {
990 try {
991 r.thread.updateTimeZone();
992 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800993 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 }
995 }
996 }
997 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700998 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700999 case CLEAR_DNS_CACHE: {
1000 synchronized (ActivityManagerService.this) {
1001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1002 ProcessRecord r = mLruProcesses.get(i);
1003 if (r.thread != null) {
1004 try {
1005 r.thread.clearDnsCache();
1006 } catch (RemoteException ex) {
1007 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1008 }
1009 }
1010 }
1011 }
1012 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001013 case UPDATE_HTTP_PROXY: {
1014 ProxyProperties proxy = (ProxyProperties)msg.obj;
1015 String host = "";
1016 String port = "";
1017 String exclList = "";
1018 if (proxy != null) {
1019 host = proxy.getHost();
1020 port = Integer.toString(proxy.getPort());
1021 exclList = proxy.getExclusionList();
1022 }
1023 synchronized (ActivityManagerService.this) {
1024 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1025 ProcessRecord r = mLruProcesses.get(i);
1026 if (r.thread != null) {
1027 try {
1028 r.thread.setHttpProxy(host, port, exclList);
1029 } catch (RemoteException ex) {
1030 Slog.w(TAG, "Failed to update http proxy for: " +
1031 r.info.processName);
1032 }
1033 }
1034 }
1035 }
1036 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 case SHOW_UID_ERROR_MSG: {
1038 // XXX This is a temporary dialog, no need to localize.
1039 AlertDialog d = new BaseErrorDialog(mContext);
1040 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1041 d.setCancelable(false);
1042 d.setTitle("System UIDs Inconsistent");
1043 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
Christian Mehlmauer7664e202010-07-20 08:46:17 +02001044 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1046 mUidAlert = d;
1047 d.show();
1048 } break;
1049 case IM_FEELING_LUCKY_MSG: {
1050 if (mUidAlert != null) {
1051 mUidAlert.dismiss();
1052 mUidAlert = null;
1053 }
1054 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001056 if (mDidDexOpt) {
1057 mDidDexOpt = false;
1058 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1059 nmsg.obj = msg.obj;
1060 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1061 return;
1062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 ProcessRecord app = (ProcessRecord)msg.obj;
1064 synchronized (ActivityManagerService.this) {
1065 processStartTimedOutLocked(app);
1066 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001067 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001068 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1069 synchronized (ActivityManagerService.this) {
1070 doPendingActivityLaunchesLocked(true);
1071 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001072 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001073 case KILL_APPLICATION_MSG: {
1074 synchronized (ActivityManagerService.this) {
1075 int uid = msg.arg1;
1076 boolean restart = (msg.arg2 == 1);
1077 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001078 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001079 }
1080 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001081 case FINALIZE_PENDING_INTENT_MSG: {
1082 ((PendingIntentRecord)msg.obj).completeFinalize();
1083 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001084 case POST_HEAVY_NOTIFICATION_MSG: {
1085 INotificationManager inm = NotificationManager.getService();
1086 if (inm == null) {
1087 return;
1088 }
1089
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001090 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001091 ProcessRecord process = root.app;
1092 if (process == null) {
1093 return;
1094 }
1095
1096 try {
1097 Context context = mContext.createPackageContext(process.info.packageName, 0);
1098 String text = mContext.getString(R.string.heavy_weight_notification,
1099 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1100 Notification notification = new Notification();
1101 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1102 notification.when = 0;
1103 notification.flags = Notification.FLAG_ONGOING_EVENT;
1104 notification.tickerText = text;
1105 notification.defaults = 0; // please be quiet
1106 notification.sound = null;
1107 notification.vibrate = null;
1108 notification.setLatestEventInfo(context, text,
1109 mContext.getText(R.string.heavy_weight_notification_detail),
1110 PendingIntent.getActivity(mContext, 0, root.intent,
1111 PendingIntent.FLAG_CANCEL_CURRENT));
1112
1113 try {
1114 int[] outId = new int[1];
1115 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1116 notification, outId);
1117 } catch (RuntimeException e) {
1118 Slog.w(ActivityManagerService.TAG,
1119 "Error showing notification for heavy-weight app", e);
1120 } catch (RemoteException e) {
1121 }
1122 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001123 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001124 }
1125 } break;
1126 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1127 INotificationManager inm = NotificationManager.getService();
1128 if (inm == null) {
1129 return;
1130 }
1131 try {
1132 inm.cancelNotification("android",
1133 R.string.heavy_weight_notification);
1134 } catch (RuntimeException e) {
1135 Slog.w(ActivityManagerService.TAG,
1136 "Error canceling notification for service", e);
1137 } catch (RemoteException e) {
1138 }
1139 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001140 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1141 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001142 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001143 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001144 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1145 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001146 }
1147 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001148 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1149 synchronized (ActivityManagerService.this) {
1150 ActivityRecord ar = (ActivityRecord)msg.obj;
1151 if (mCompatModeDialog != null) {
1152 if (mCompatModeDialog.mAppInfo.packageName.equals(
1153 ar.info.applicationInfo.packageName)) {
1154 return;
1155 }
1156 mCompatModeDialog.dismiss();
1157 mCompatModeDialog = null;
1158 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001159 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001160 if (mCompatModePackages.getPackageAskCompatModeLocked(
1161 ar.packageName)) {
1162 int mode = mCompatModePackages.computeCompatModeLocked(
1163 ar.info.applicationInfo);
1164 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1165 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1166 mCompatModeDialog = new CompatModeDialog(
1167 ActivityManagerService.this, mContext,
1168 ar.info.applicationInfo);
1169 mCompatModeDialog.show();
1170 }
1171 }
1172 }
1173 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001174 break;
1175 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001176 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001177 final int pid = msg.arg1;
1178 final int uid = msg.arg2;
1179 final boolean foregroundActivities = (Boolean) msg.obj;
1180 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001181 break;
1182 }
1183 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001184 final int pid = msg.arg1;
1185 final int uid = msg.arg2;
1186 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001187 break;
1188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 }
1190 }
1191 };
1192
1193 public static void setSystemProcess() {
1194 try {
1195 ActivityManagerService m = mSelf;
1196
1197 ServiceManager.addService("activity", m);
1198 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001199 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 if (MONITOR_CPU_USAGE) {
1201 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 ServiceManager.addService("permission", new PermissionController(m));
1204
1205 ApplicationInfo info =
1206 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001207 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001208 mSystemThread.installSystemApplicationInfo(info);
1209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 synchronized (mSelf) {
1211 ProcessRecord app = mSelf.newProcessRecordLocked(
1212 mSystemThread.getApplicationThread(), info,
1213 info.processName);
1214 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001215 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001216 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1218 synchronized (mSelf.mPidsSelfLocked) {
1219 mSelf.mPidsSelfLocked.put(app.pid, app);
1220 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001221 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 }
1223 } catch (PackageManager.NameNotFoundException e) {
1224 throw new RuntimeException(
1225 "Unable to find android system package", e);
1226 }
1227 }
1228
1229 public void setWindowManager(WindowManagerService wm) {
1230 mWindowManager = wm;
1231 }
1232
1233 public static final Context main(int factoryTest) {
1234 AThread thr = new AThread();
1235 thr.start();
1236
1237 synchronized (thr) {
1238 while (thr.mService == null) {
1239 try {
1240 thr.wait();
1241 } catch (InterruptedException e) {
1242 }
1243 }
1244 }
1245
1246 ActivityManagerService m = thr.mService;
1247 mSelf = m;
1248 ActivityThread at = ActivityThread.systemMain();
1249 mSystemThread = at;
1250 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001251 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 m.mContext = context;
1253 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001254 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255
1256 m.mBatteryStatsService.publish(context);
1257 m.mUsageStatsService.publish(context);
1258
1259 synchronized (thr) {
1260 thr.mReady = true;
1261 thr.notifyAll();
1262 }
1263
1264 m.startRunning(null, null, null, null);
1265
1266 return context;
1267 }
1268
1269 public static ActivityManagerService self() {
1270 return mSelf;
1271 }
1272
1273 static class AThread extends Thread {
1274 ActivityManagerService mService;
1275 boolean mReady = false;
1276
1277 public AThread() {
1278 super("ActivityManager");
1279 }
1280
1281 public void run() {
1282 Looper.prepare();
1283
1284 android.os.Process.setThreadPriority(
1285 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001286 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287
1288 ActivityManagerService m = new ActivityManagerService();
1289
1290 synchronized (this) {
1291 mService = m;
1292 notifyAll();
1293 }
1294
1295 synchronized (this) {
1296 while (!mReady) {
1297 try {
1298 wait();
1299 } catch (InterruptedException e) {
1300 }
1301 }
1302 }
1303
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001304 // For debug builds, log event loop stalls to dropbox for analysis.
1305 if (StrictMode.conditionallyEnableDebugLogging()) {
1306 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1307 }
1308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 Looper.loop();
1310 }
1311 }
1312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 static class MemBinder extends Binder {
1314 ActivityManagerService mActivityManagerService;
1315 MemBinder(ActivityManagerService activityManagerService) {
1316 mActivityManagerService = activityManagerService;
1317 }
1318
1319 @Override
1320 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001321 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 }
1323 }
1324
Chet Haase9c1e23b2011-03-24 10:51:31 -07001325 static class GraphicsBinder extends Binder {
1326 ActivityManagerService mActivityManagerService;
1327 GraphicsBinder(ActivityManagerService activityManagerService) {
1328 mActivityManagerService = activityManagerService;
1329 }
1330
1331 @Override
1332 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001333 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001334 }
1335 }
1336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 static class CpuBinder extends Binder {
1338 ActivityManagerService mActivityManagerService;
1339 CpuBinder(ActivityManagerService activityManagerService) {
1340 mActivityManagerService = activityManagerService;
1341 }
1342
1343 @Override
1344 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1345 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001346 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1347 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1348 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 }
1350 }
1351 }
1352
1353 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001354 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 File dataDir = Environment.getDataDirectory();
1357 File systemDir = new File(dataDir, "system");
1358 systemDir.mkdirs();
1359 mBatteryStatsService = new BatteryStatsService(new File(
1360 systemDir, "batterystats.bin").toString());
1361 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001362 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001363 mOnBattery = DEBUG_POWER ? true
1364 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001365 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001367 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001368 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369
Jack Palevichb90d28c2009-07-22 15:35:24 -07001370 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1371 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1372
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001373 mConfiguration.setToDefaults();
1374 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 mProcessStats.init();
1376
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001377 mCompatModePackages = new CompatModePackages(this, systemDir);
1378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 // Add ourself to the Watchdog monitors.
1380 Watchdog.getInstance().addMonitor(this);
1381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 mProcessStatsThread = new Thread("ProcessStats") {
1383 public void run() {
1384 while (true) {
1385 try {
1386 try {
1387 synchronized(this) {
1388 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001389 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001391 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 // + ", write delay=" + nextWriteDelay);
1393 if (nextWriteDelay < nextCpuDelay) {
1394 nextCpuDelay = nextWriteDelay;
1395 }
1396 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001397 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 this.wait(nextCpuDelay);
1399 }
1400 }
1401 } catch (InterruptedException e) {
1402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 updateCpuStatsNow();
1404 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001405 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 }
1407 }
1408 }
1409 };
1410 mProcessStatsThread.start();
1411 }
1412
1413 @Override
1414 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1415 throws RemoteException {
1416 try {
1417 return super.onTransact(code, data, reply, flags);
1418 } catch (RuntimeException e) {
1419 // The activity manager only throws security exceptions, so let's
1420 // log all others.
1421 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001422 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 }
1424 throw e;
1425 }
1426 }
1427
1428 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001429 final long now = SystemClock.uptimeMillis();
1430 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1431 return;
1432 }
1433 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1434 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 mProcessStatsThread.notify();
1436 }
1437 }
1438 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 void updateCpuStatsNow() {
1441 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001442 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 final long now = SystemClock.uptimeMillis();
1444 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001447 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1448 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 haveNewCpuStats = true;
1450 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001451 //Slog.i(TAG, mProcessStats.printCurrentState());
1452 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 // + mProcessStats.getTotalCpuPercent() + "%");
1454
Joe Onorato8a9b2202010-02-26 18:56:32 -08001455 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 if ("true".equals(SystemProperties.get("events.cpu"))) {
1457 int user = mProcessStats.getLastUserTime();
1458 int system = mProcessStats.getLastSystemTime();
1459 int iowait = mProcessStats.getLastIoWaitTime();
1460 int irq = mProcessStats.getLastIrqTime();
1461 int softIrq = mProcessStats.getLastSoftIrqTime();
1462 int idle = mProcessStats.getLastIdleTime();
1463
1464 int total = user + system + iowait + irq + softIrq + idle;
1465 if (total == 0) total = 1;
1466
Doug Zongker2bec3d42009-12-04 12:52:44 -08001467 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 ((user+system+iowait+irq+softIrq) * 100) / total,
1469 (user * 100) / total,
1470 (system * 100) / total,
1471 (iowait * 100) / total,
1472 (irq * 100) / total,
1473 (softIrq * 100) / total);
1474 }
1475 }
1476
Amith Yamasanie43530a2009-08-21 13:11:37 -07001477 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001478 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001479 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 synchronized(mPidsSelfLocked) {
1481 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001482 if (mOnBattery) {
1483 int perc = bstats.startAddingCpuLocked();
1484 int totalUTime = 0;
1485 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001486 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001488 ProcessStats.Stats st = mProcessStats.getStats(i);
1489 if (!st.working) {
1490 continue;
1491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001493 int otherUTime = (st.rel_utime*perc)/100;
1494 int otherSTime = (st.rel_stime*perc)/100;
1495 totalUTime += otherUTime;
1496 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 if (pr != null) {
1498 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001499 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1500 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001501 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001502 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001503 } else {
1504 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001505 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001506 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001507 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1508 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001509 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001510 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 }
1512 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001513 bstats.finishAddingCpuLocked(perc, totalUTime,
1514 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 }
1516 }
1517 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1520 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001521 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 }
1523 }
1524 }
1525 }
1526
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001527 @Override
1528 public void batteryNeedsCpuUpdate() {
1529 updateCpuStatsNow();
1530 }
1531
1532 @Override
1533 public void batteryPowerChanged(boolean onBattery) {
1534 // When plugging in, update the CPU stats first before changing
1535 // the plug state.
1536 updateCpuStatsNow();
1537 synchronized (this) {
1538 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001539 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001540 }
1541 }
1542 }
1543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 /**
1545 * Initialize the application bind args. These are passed to each
1546 * process when the bindApplication() IPC is sent to the process. They're
1547 * lazily setup to make sure the services are running when they're asked for.
1548 */
1549 private HashMap<String, IBinder> getCommonServicesLocked() {
1550 if (mAppBindArgs == null) {
1551 mAppBindArgs = new HashMap<String, IBinder>();
1552
1553 // Setup the application init args
1554 mAppBindArgs.put("package", ServiceManager.getService("package"));
1555 mAppBindArgs.put("window", ServiceManager.getService("window"));
1556 mAppBindArgs.put(Context.ALARM_SERVICE,
1557 ServiceManager.getService(Context.ALARM_SERVICE));
1558 }
1559 return mAppBindArgs;
1560 }
1561
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001562 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 if (mFocusedActivity != r) {
1564 mFocusedActivity = r;
1565 mWindowManager.setFocusedApp(r, true);
1566 }
1567 }
1568
Dianne Hackborn906497c2010-05-10 15:57:38 -07001569 private final void updateLruProcessInternalLocked(ProcessRecord app,
1570 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001572 int lrui = mLruProcesses.indexOf(app);
1573 if (lrui >= 0) mLruProcesses.remove(lrui);
1574
1575 int i = mLruProcesses.size()-1;
1576 int skipTop = 0;
1577
Dianne Hackborn906497c2010-05-10 15:57:38 -07001578 app.lruSeq = mLruSeq;
1579
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001580 // compute the new weight for this process.
1581 if (updateActivityTime) {
1582 app.lastActivityTime = SystemClock.uptimeMillis();
1583 }
1584 if (app.activities.size() > 0) {
1585 // If this process has activities, we more strongly want to keep
1586 // it around.
1587 app.lruWeight = app.lastActivityTime;
1588 } else if (app.pubProviders.size() > 0) {
1589 // If this process contains content providers, we want to keep
1590 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001591 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001592 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001593 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001594 } else {
1595 // If this process doesn't have activities, we less strongly
1596 // want to keep it around, and generally want to avoid getting
1597 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001598 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001599 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001600 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001601 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001602
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001603 while (i >= 0) {
1604 ProcessRecord p = mLruProcesses.get(i);
1605 // If this app shouldn't be in front of the first N background
1606 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001607 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001608 skipTop--;
1609 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001610 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001611 mLruProcesses.add(i+1, app);
1612 break;
1613 }
1614 i--;
1615 }
1616 if (i < 0) {
1617 mLruProcesses.add(0, app);
1618 }
1619
Dianne Hackborn906497c2010-05-10 15:57:38 -07001620 // If the app is currently using a content provider or service,
1621 // bump those processes as well.
1622 if (app.connections.size() > 0) {
1623 for (ConnectionRecord cr : app.connections) {
1624 if (cr.binding != null && cr.binding.service != null
1625 && cr.binding.service.app != null
1626 && cr.binding.service.app.lruSeq != mLruSeq) {
1627 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1628 updateActivityTime, i+1);
1629 }
1630 }
1631 }
1632 if (app.conProviders.size() > 0) {
1633 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001634 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1635 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001636 updateActivityTime, i+1);
1637 }
1638 }
1639 }
1640
Joe Onorato8a9b2202010-02-26 18:56:32 -08001641 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 if (oomAdj) {
1643 updateOomAdjLocked();
1644 }
1645 }
1646
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001647 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001648 boolean oomAdj, boolean updateActivityTime) {
1649 mLruSeq++;
1650 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1651 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001652
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001653 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 String processName, int uid) {
1655 if (uid == Process.SYSTEM_UID) {
1656 // The system gets to run in any process. If there are multiple
1657 // processes with the same uid, just pick the first (this
1658 // should never happen).
1659 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1660 processName);
1661 return procs != null ? procs.valueAt(0) : null;
1662 }
1663 ProcessRecord proc = mProcessNames.get(processName, uid);
1664 return proc;
1665 }
1666
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001667 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001668 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001669 try {
1670 if (pm.performDexOpt(packageName)) {
1671 mDidDexOpt = true;
1672 }
1673 } catch (RemoteException e) {
1674 }
1675 }
1676
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001677 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 int transit = mWindowManager.getPendingAppTransition();
1679 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1680 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1681 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1682 }
1683
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001684 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001686 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1688 // We don't have to do anything more if:
1689 // (1) There is an existing application record; and
1690 // (2) The caller doesn't think it is dead, OR there is no thread
1691 // object attached to it so we know it couldn't have crashed; and
1692 // (3) There is a pid assigned to it, so it is either starting or
1693 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001694 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 + " app=" + app + " knownToBeDead=" + knownToBeDead
1696 + " thread=" + (app != null ? app.thread : null)
1697 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001698 if (app != null && app.pid > 0) {
1699 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001700 // We already have the app running, or are waiting for it to
1701 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001702 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001703 // If this is a new package in the process, add the package to the list
1704 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001705 return app;
1706 } else {
1707 // An application record is attached to a previous process,
1708 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001709 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001710 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001712 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714 String hostingNameStr = hostingName != null
1715 ? hostingName.flattenToShortString() : null;
1716
1717 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1718 // If we are in the background, then check to see if this process
1719 // is bad. If so, we will just silently fail.
1720 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001721 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1722 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001723 return null;
1724 }
1725 } else {
1726 // When the user is explicitly starting a process, then clear its
1727 // crash count so that we won't make it bad until they see at
1728 // least one crash dialog again, and make the process good again
1729 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001730 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1731 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001732 mProcessCrashTimes.remove(info.processName, info.uid);
1733 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001734 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001735 info.processName);
1736 mBadProcesses.remove(info.processName, info.uid);
1737 if (app != null) {
1738 app.bad = false;
1739 }
1740 }
1741 }
1742
1743 if (app == null) {
1744 app = newProcessRecordLocked(null, info, processName);
1745 mProcessNames.put(processName, info.uid, app);
1746 } else {
1747 // If this is a new package in the process, add the package to the list
1748 app.addPackage(info.packageName);
1749 }
1750
1751 // If the system is not ready yet, then hold off on starting this
1752 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001753 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001754 && !isAllowedWhileBooting(info)
1755 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 if (!mProcessesOnHold.contains(app)) {
1757 mProcessesOnHold.add(app);
1758 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001759 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001760 return app;
1761 }
1762
1763 startProcessLocked(app, hostingType, hostingNameStr);
1764 return (app.pid != 0) ? app : null;
1765 }
1766
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001767 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1768 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1769 }
1770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001771 private final void startProcessLocked(ProcessRecord app,
1772 String hostingType, String hostingNameStr) {
1773 if (app.pid > 0 && app.pid != MY_PID) {
1774 synchronized (mPidsSelfLocked) {
1775 mPidsSelfLocked.remove(app.pid);
1776 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1777 }
1778 app.pid = 0;
1779 }
1780
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001781 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1782 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001783 mProcessesOnHold.remove(app);
1784
1785 updateCpuStats();
1786
1787 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1788 mProcDeaths[0] = 0;
1789
1790 try {
1791 int uid = app.info.uid;
1792 int[] gids = null;
1793 try {
1794 gids = mContext.getPackageManager().getPackageGids(
1795 app.info.packageName);
1796 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001797 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 }
1799 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1800 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1801 && mTopComponent != null
1802 && app.processName.equals(mTopComponent.getPackageName())) {
1803 uid = 0;
1804 }
1805 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1806 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1807 uid = 0;
1808 }
1809 }
1810 int debugFlags = 0;
1811 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1812 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001813 // Also turn on CheckJNI for debuggable apps. It's quite
1814 // awkward to turn on otherwise.
1815 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001817 // Run the app in safe mode if its manifest requests so or the
1818 // system is booted in safe mode.
1819 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1820 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001821 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1824 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1825 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001826 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1827 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 if ("1".equals(SystemProperties.get("debug.assert"))) {
1830 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1831 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001832
1833 // Start the process. It will either succeed and return a result containing
1834 // the PID of the new process, or else throw a RuntimeException.
1835 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001836 app.processName, uid, uid, gids, debugFlags,
1837 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1840 synchronized (bs) {
1841 if (bs.isOnBattery()) {
1842 app.batteryStats.incStartsLocked();
1843 }
1844 }
1845
Jeff Brown3f9dd282011-07-08 20:02:19 -07001846 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 app.processName, hostingType,
1848 hostingNameStr != null ? hostingNameStr : "");
1849
1850 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001851 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001852 }
1853
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001854 StringBuilder buf = mStringBuilder;
1855 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 buf.append("Start proc ");
1857 buf.append(app.processName);
1858 buf.append(" for ");
1859 buf.append(hostingType);
1860 if (hostingNameStr != null) {
1861 buf.append(" ");
1862 buf.append(hostingNameStr);
1863 }
1864 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001865 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001866 buf.append(" uid=");
1867 buf.append(uid);
1868 buf.append(" gids={");
1869 if (gids != null) {
1870 for (int gi=0; gi<gids.length; gi++) {
1871 if (gi != 0) buf.append(", ");
1872 buf.append(gids[gi]);
1873
1874 }
1875 }
1876 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001877 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001878 app.pid = startResult.pid;
1879 app.usingWrapper = startResult.usingWrapper;
1880 app.removed = false;
1881 synchronized (mPidsSelfLocked) {
1882 this.mPidsSelfLocked.put(startResult.pid, app);
1883 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1884 msg.obj = app;
1885 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1886 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 }
1888 } catch (RuntimeException e) {
1889 // XXX do better error recovery.
1890 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001891 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001892 }
1893 }
1894
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001895 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001896 if (resumed) {
1897 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1898 } else {
1899 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1900 }
1901 }
1902
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001903 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001904 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1905 && mTopAction == null) {
1906 // We are running in factory test mode, but unable to find
1907 // the factory test app, so just sit around displaying the
1908 // error message and don't try to start anything.
1909 return false;
1910 }
1911 Intent intent = new Intent(
1912 mTopAction,
1913 mTopData != null ? Uri.parse(mTopData) : null);
1914 intent.setComponent(mTopComponent);
1915 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1916 intent.addCategory(Intent.CATEGORY_HOME);
1917 }
1918 ActivityInfo aInfo =
1919 intent.resolveActivityInfo(mContext.getPackageManager(),
1920 STOCK_PM_FLAGS);
1921 if (aInfo != null) {
1922 intent.setComponent(new ComponentName(
1923 aInfo.applicationInfo.packageName, aInfo.name));
1924 // Don't do this if the home app is currently being
1925 // instrumented.
1926 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1927 aInfo.applicationInfo.uid);
1928 if (app == null || app.instrumentationClass == null) {
1929 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001930 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001931 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001932 }
1933 }
1934
1935
1936 return true;
1937 }
1938
1939 /**
1940 * Starts the "new version setup screen" if appropriate.
1941 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001942 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001943 // Only do this once per boot.
1944 if (mCheckedForSetup) {
1945 return;
1946 }
1947
1948 // We will show this screen if the current one is a different
1949 // version than the last one shown, and we are not running in
1950 // low-level factory test mode.
1951 final ContentResolver resolver = mContext.getContentResolver();
1952 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1953 Settings.Secure.getInt(resolver,
1954 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1955 mCheckedForSetup = true;
1956
1957 // See if we should be showing the platform update setup UI.
1958 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1959 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1960 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1961
1962 // We don't allow third party apps to replace this.
1963 ResolveInfo ri = null;
1964 for (int i=0; ris != null && i<ris.size(); i++) {
1965 if ((ris.get(i).activityInfo.applicationInfo.flags
1966 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1967 ri = ris.get(i);
1968 break;
1969 }
1970 }
1971
1972 if (ri != null) {
1973 String vers = ri.activityInfo.metaData != null
1974 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
1975 : null;
1976 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
1977 vers = ri.activityInfo.applicationInfo.metaData.getString(
1978 Intent.METADATA_SETUP_VERSION);
1979 }
1980 String lastVers = Settings.Secure.getString(
1981 resolver, Settings.Secure.LAST_SETUP_SHOWN);
1982 if (vers != null && !vers.equals(lastVers)) {
1983 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1984 intent.setComponent(new ComponentName(
1985 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001986 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001987 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001988 }
1989 }
1990 }
1991 }
1992
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001993 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001994 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001995 }
1996
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001997 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001998 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001999 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2000 }
2001 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002002
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002003 public void setFrontActivityScreenCompatMode(int mode) {
2004 synchronized (this) {
2005 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2006 }
2007 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002008
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002009 public int getPackageScreenCompatMode(String packageName) {
2010 synchronized (this) {
2011 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2012 }
2013 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002014
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002015 public void setPackageScreenCompatMode(String packageName, int mode) {
2016 synchronized (this) {
2017 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002018 }
2019 }
2020
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002021 public boolean getPackageAskScreenCompat(String packageName) {
2022 synchronized (this) {
2023 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2024 }
2025 }
2026
2027 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2028 synchronized (this) {
2029 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2030 }
2031 }
2032
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002033 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002034 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002035
2036 final int identHash = System.identityHashCode(r);
2037 updateUsageStats(r, true);
2038
2039 int i = mWatchers.beginBroadcast();
2040 while (i > 0) {
2041 i--;
2042 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2043 if (w != null) {
2044 try {
2045 w.activityResuming(identHash);
2046 } catch (RemoteException e) {
2047 }
2048 }
2049 }
2050 mWatchers.finishBroadcast();
2051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052
Jeff Sharkeya4620792011-05-20 15:29:23 -07002053 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2054 int i = mProcessObservers.beginBroadcast();
2055 while (i > 0) {
2056 i--;
2057 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2058 if (observer != null) {
2059 try {
2060 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2061 } catch (RemoteException e) {
2062 }
2063 }
2064 }
2065 mProcessObservers.finishBroadcast();
2066 }
2067
2068 private void dispatchProcessDied(int pid, int uid) {
2069 int i = mProcessObservers.beginBroadcast();
2070 while (i > 0) {
2071 i--;
2072 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2073 if (observer != null) {
2074 try {
2075 observer.onProcessDied(pid, uid);
2076 } catch (RemoteException e) {
2077 }
2078 }
2079 }
2080 mProcessObservers.finishBroadcast();
2081 }
2082
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002083 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002084 final int N = mPendingActivityLaunches.size();
2085 if (N <= 0) {
2086 return;
2087 }
2088 for (int i=0; i<N; i++) {
2089 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002090 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002091 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2092 doResume && i == (N-1));
2093 }
2094 mPendingActivityLaunches.clear();
2095 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002096
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002097 public final int startActivity(IApplicationThread caller,
2098 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2099 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002100 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2101 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002102 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002103 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002104 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2105 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002106 }
2107
2108 public final WaitResult startActivityAndWait(IApplicationThread caller,
2109 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2110 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002111 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2112 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002113 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002114 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002115 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002116 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2117 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002118 return res;
2119 }
2120
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002121 public final int startActivityWithConfig(IApplicationThread caller,
2122 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2123 int grantedMode, IBinder resultTo,
2124 String resultWho, int requestCode, boolean onlyIfNeeded,
2125 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002126 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002127 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002128 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002129 }
2130
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002131 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002132 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002133 IBinder resultTo, String resultWho, int requestCode,
2134 int flagsMask, int flagsValues) {
2135 // Refuse possible leaked file descriptors
2136 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2137 throw new IllegalArgumentException("File descriptors passed in Intent");
2138 }
2139
2140 IIntentSender sender = intent.getTarget();
2141 if (!(sender instanceof PendingIntentRecord)) {
2142 throw new IllegalArgumentException("Bad PendingIntent object");
2143 }
2144
2145 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002146
2147 synchronized (this) {
2148 // If this is coming from the currently resumed activity, it is
2149 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002150 if (mMainStack.mResumedActivity != null
2151 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002152 Binder.getCallingUid()) {
2153 mAppSwitchesAllowedTime = 0;
2154 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002155 }
2156
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002157 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002158 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2159 }
2160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 public boolean startNextMatchingActivity(IBinder callingActivity,
2162 Intent intent) {
2163 // Refuse possible leaked file descriptors
2164 if (intent != null && intent.hasFileDescriptors() == true) {
2165 throw new IllegalArgumentException("File descriptors passed in Intent");
2166 }
2167
2168 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002169 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2170 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 return false;
2172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 if (r.app == null || r.app.thread == null) {
2174 // The caller is not running... d'oh!
2175 return false;
2176 }
2177 intent = new Intent(intent);
2178 // The caller is not allowed to change the data.
2179 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2180 // And we are resetting to find the next component...
2181 intent.setComponent(null);
2182
2183 ActivityInfo aInfo = null;
2184 try {
2185 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002186 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002188 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002189
2190 // Look for the original activity in the list...
2191 final int N = resolves != null ? resolves.size() : 0;
2192 for (int i=0; i<N; i++) {
2193 ResolveInfo rInfo = resolves.get(i);
2194 if (rInfo.activityInfo.packageName.equals(r.packageName)
2195 && rInfo.activityInfo.name.equals(r.info.name)) {
2196 // We found the current one... the next matching is
2197 // after it.
2198 i++;
2199 if (i<N) {
2200 aInfo = resolves.get(i).activityInfo;
2201 }
2202 break;
2203 }
2204 }
2205 } catch (RemoteException e) {
2206 }
2207
2208 if (aInfo == null) {
2209 // Nobody who is next!
2210 return false;
2211 }
2212
2213 intent.setComponent(new ComponentName(
2214 aInfo.applicationInfo.packageName, aInfo.name));
2215 intent.setFlags(intent.getFlags()&~(
2216 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2217 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2218 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2219 Intent.FLAG_ACTIVITY_NEW_TASK));
2220
2221 // Okay now we need to start the new activity, replacing the
2222 // currently running activity. This is a little tricky because
2223 // we want to start the new one as if the current one is finished,
2224 // but not finish the current one first so that there is no flicker.
2225 // And thus...
2226 final boolean wasFinishing = r.finishing;
2227 r.finishing = true;
2228
2229 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002230 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 final String resultWho = r.resultWho;
2232 final int requestCode = r.requestCode;
2233 r.resultTo = null;
2234 if (resultTo != null) {
2235 resultTo.removeResultsLocked(r, resultWho, requestCode);
2236 }
2237
2238 final long origId = Binder.clearCallingIdentity();
2239 // XXX we are not dealing with propagating grantedUriPermissions...
2240 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002241 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002242 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002243 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 Binder.restoreCallingIdentity(origId);
2245
2246 r.finishing = wasFinishing;
2247 if (res != START_SUCCESS) {
2248 return false;
2249 }
2250 return true;
2251 }
2252 }
2253
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002254 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 Intent intent, String resolvedType, IBinder resultTo,
2256 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002257
2258 // This is so super not safe, that only the system (or okay root)
2259 // can do it.
2260 final int callingUid = Binder.getCallingUid();
2261 if (callingUid != 0 && callingUid != Process.myUid()) {
2262 throw new SecurityException(
2263 "startActivityInPackage only available to the system");
2264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002265
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002266 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002267 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2268 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002269 }
2270
2271 public final int startActivities(IApplicationThread caller,
2272 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2273 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2274 }
2275
2276 public final int startActivitiesInPackage(int uid,
2277 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2278
2279 // This is so super not safe, that only the system (or okay root)
2280 // can do it.
2281 final int callingUid = Binder.getCallingUid();
2282 if (callingUid != 0 && callingUid != Process.myUid()) {
2283 throw new SecurityException(
2284 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 }
2286
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002287 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002288 }
2289
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002290 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002292 // Quick case: check if the top-most recent task is the same.
2293 if (N > 0 && mRecentTasks.get(0) == task) {
2294 return;
2295 }
2296 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 for (int i=0; i<N; i++) {
2298 TaskRecord tr = mRecentTasks.get(i);
2299 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2300 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2301 mRecentTasks.remove(i);
2302 i--;
2303 N--;
2304 if (task.intent == null) {
2305 // If the new recent task we are adding is not fully
2306 // specified, then replace it with the existing recent task.
2307 task = tr;
2308 }
2309 }
2310 }
2311 if (N >= MAX_RECENT_TASKS) {
2312 mRecentTasks.remove(N-1);
2313 }
2314 mRecentTasks.add(0, task);
2315 }
2316
2317 public void setRequestedOrientation(IBinder token,
2318 int requestedOrientation) {
2319 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002320 ActivityRecord r = mMainStack.isInStackLocked(token);
2321 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 return;
2323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324 final long origId = Binder.clearCallingIdentity();
2325 mWindowManager.setAppOrientation(r, requestedOrientation);
2326 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002327 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 r.mayFreezeScreenLocked(r.app) ? r : null);
2329 if (config != null) {
2330 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002331 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002332 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 }
2334 }
2335 Binder.restoreCallingIdentity(origId);
2336 }
2337 }
2338
2339 public int getRequestedOrientation(IBinder token) {
2340 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002341 ActivityRecord r = mMainStack.isInStackLocked(token);
2342 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002343 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002345 return mWindowManager.getAppOrientation(r);
2346 }
2347 }
2348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 /**
2350 * This is the internal entry point for handling Activity.finish().
2351 *
2352 * @param token The Binder token referencing the Activity we want to finish.
2353 * @param resultCode Result code, if any, from this Activity.
2354 * @param resultData Result data (Intent), if any, from this Activity.
2355 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002356 * @return Returns true if the activity successfully finished, or false if it is still running.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357 */
2358 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2359 // Refuse possible leaked file descriptors
2360 if (resultData != null && resultData.hasFileDescriptors() == true) {
2361 throw new IllegalArgumentException("File descriptors passed in Intent");
2362 }
2363
2364 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002365 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002367 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002368 if (next != null) {
2369 // ask watcher if this is allowed
2370 boolean resumeOK = true;
2371 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002372 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002374 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 }
2376
2377 if (!resumeOK) {
2378 return false;
2379 }
2380 }
2381 }
2382 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002383 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 resultData, "app-request");
2385 Binder.restoreCallingIdentity(origId);
2386 return res;
2387 }
2388 }
2389
Dianne Hackborn860755f2010-06-03 18:47:52 -07002390 public final void finishHeavyWeightApp() {
2391 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2392 != PackageManager.PERMISSION_GRANTED) {
2393 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2394 + Binder.getCallingPid()
2395 + ", uid=" + Binder.getCallingUid()
2396 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2397 Slog.w(TAG, msg);
2398 throw new SecurityException(msg);
2399 }
2400
2401 synchronized(this) {
2402 if (mHeavyWeightProcess == null) {
2403 return;
2404 }
2405
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002406 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002407 mHeavyWeightProcess.activities);
2408 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002409 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002410 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002411 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002412 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002413 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002414 null, "finish-heavy");
2415 }
2416 }
2417 }
2418
2419 mHeavyWeightProcess = null;
2420 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2421 }
2422 }
2423
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002424 public void crashApplication(int uid, int initialPid, String packageName,
2425 String message) {
2426 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2427 != PackageManager.PERMISSION_GRANTED) {
2428 String msg = "Permission Denial: crashApplication() from pid="
2429 + Binder.getCallingPid()
2430 + ", uid=" + Binder.getCallingUid()
2431 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2432 Slog.w(TAG, msg);
2433 throw new SecurityException(msg);
2434 }
2435
2436 synchronized(this) {
2437 ProcessRecord proc = null;
2438
2439 // Figure out which process to kill. We don't trust that initialPid
2440 // still has any relation to current pids, so must scan through the
2441 // list.
2442 synchronized (mPidsSelfLocked) {
2443 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2444 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2445 if (p.info.uid != uid) {
2446 continue;
2447 }
2448 if (p.pid == initialPid) {
2449 proc = p;
2450 break;
2451 }
2452 for (String str : p.pkgList) {
2453 if (str.equals(packageName)) {
2454 proc = p;
2455 }
2456 }
2457 }
2458 }
2459
2460 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002461 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002462 + " initialPid=" + initialPid
2463 + " packageName=" + packageName);
2464 return;
2465 }
2466
2467 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002468 if (proc.pid == Process.myPid()) {
2469 Log.w(TAG, "crashApplication: trying to crash self!");
2470 return;
2471 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002472 long ident = Binder.clearCallingIdentity();
2473 try {
2474 proc.thread.scheduleCrash(message);
2475 } catch (RemoteException e) {
2476 }
2477 Binder.restoreCallingIdentity(ident);
2478 }
2479 }
2480 }
2481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002482 public final void finishSubActivity(IBinder token, String resultWho,
2483 int requestCode) {
2484 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002485 ActivityRecord self = mMainStack.isInStackLocked(token);
2486 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 return;
2488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489
2490 final long origId = Binder.clearCallingIdentity();
2491
2492 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002493 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2494 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002495 if (r.resultTo == self && r.requestCode == requestCode) {
2496 if ((r.resultWho == null && resultWho == null) ||
2497 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002498 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002499 Activity.RESULT_CANCELED, null, "request-sub");
2500 }
2501 }
2502 }
2503
2504 Binder.restoreCallingIdentity(origId);
2505 }
2506 }
2507
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002508 public boolean willActivityBeVisible(IBinder token) {
2509 synchronized(this) {
2510 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002511 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2512 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002513 if (r == token) {
2514 return true;
2515 }
2516 if (r.fullscreen && !r.finishing) {
2517 return false;
2518 }
2519 }
2520 return true;
2521 }
2522 }
2523
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002524 public void overridePendingTransition(IBinder token, String packageName,
2525 int enterAnim, int exitAnim) {
2526 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002527 ActivityRecord self = mMainStack.isInStackLocked(token);
2528 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002529 return;
2530 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002531
2532 final long origId = Binder.clearCallingIdentity();
2533
2534 if (self.state == ActivityState.RESUMED
2535 || self.state == ActivityState.PAUSING) {
2536 mWindowManager.overridePendingAppTransition(packageName,
2537 enterAnim, exitAnim);
2538 }
2539
2540 Binder.restoreCallingIdentity(origId);
2541 }
2542 }
2543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002545 * Main function for removing an existing process from the activity manager
2546 * as a result of that process going away. Clears out all connections
2547 * to the process.
2548 */
2549 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002550 boolean restarting, boolean allowRestart) {
2551 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002552 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002553 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 }
2555
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002556 if (mProfileProc == app) {
2557 clearProfilerLocked();
2558 }
2559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002560 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002561 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2562 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2563 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002565 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2566 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002567 }
2568
2569 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002570 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002571
2572 boolean atTop = true;
2573 boolean hasVisibleActivities = false;
2574
2575 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002576 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002577 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 TAG, "Removing app " + app + " from history with " + i + " entries");
2579 while (i > 0) {
2580 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002581 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002582 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2584 if (r.app == app) {
2585 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002586 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002587 TAG, "Removing this entry! frozen=" + r.haveState
2588 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002589 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002590 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002591 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002592 mWindowManager.removeAppToken(r);
2593 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002594 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002596 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002597
2598 } else {
2599 // We have the current state for this activity, so
2600 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002601 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 TAG, "Keeping entry, setting app to null");
2603 if (r.visible) {
2604 hasVisibleActivities = true;
2605 }
2606 r.app = null;
2607 r.nowVisible = false;
2608 if (!r.haveState) {
2609 r.icicle = null;
2610 }
2611 }
2612
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002613 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002614 }
2615 atTop = false;
2616 }
2617
2618 app.activities.clear();
2619
2620 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002621 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 + " running instrumentation " + app.instrumentationClass);
2623 Bundle info = new Bundle();
2624 info.putString("shortMsg", "Process crashed.");
2625 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2626 }
2627
2628 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002629 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 // If there was nothing to resume, and we are not already
2631 // restarting this process, but there is a visible activity that
2632 // is hosted by the process... then make sure all visible
2633 // activities are running, taking care of restarting this
2634 // process.
2635 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002636 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637 }
2638 }
2639 }
2640 }
2641
2642 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2643 IBinder threadBinder = thread.asBinder();
2644
2645 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002646 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2647 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002648 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2649 return i;
2650 }
2651 }
2652 return -1;
2653 }
2654
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002655 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 IApplicationThread thread) {
2657 if (thread == null) {
2658 return null;
2659 }
2660
2661 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002662 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 }
2664
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002665 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 IApplicationThread thread) {
2667
2668 mProcDeaths[0]++;
2669
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002670 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2671 synchronized (stats) {
2672 stats.noteProcessDiedLocked(app.info.uid, pid);
2673 }
2674
Magnus Edlund7bb25812010-02-24 15:45:06 +01002675 // Clean up already done if the process has been re-started.
2676 if (app.pid == pid && app.thread != null &&
2677 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002678 if (!app.killedBackground) {
2679 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2680 + ") has died.");
2681 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002682 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002683 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002684 TAG, "Dying app: " + app + ", pid: " + pid
2685 + ", thread: " + thread.asBinder());
2686 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002687 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002688
2689 if (doLowMem) {
2690 // If there are no longer any background processes running,
2691 // and the app that died was not running instrumentation,
2692 // then tell everyone we are now low on memory.
2693 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002694 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2695 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002696 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697 haveBg = true;
2698 break;
2699 }
2700 }
2701
2702 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002703 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002704 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002705 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2706 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002707 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002708 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2709 // The low memory report is overriding any current
2710 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002711 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002712 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002713 rec.lastRequestedGc = 0;
2714 } else {
2715 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002717 rec.reportLowMemory = true;
2718 rec.lastLowMemory = now;
2719 mProcessesToGc.remove(rec);
2720 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721 }
2722 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002723 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 }
2725 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002726 } else if (app.pid != pid) {
2727 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002728 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002729 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002730 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002731 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002732 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 + thread.asBinder());
2734 }
2735 }
2736
Dan Egnor42471dd2010-01-07 17:25:22 -08002737 /**
2738 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002739 * @param clearTraces causes the dump file to be erased prior to the new
2740 * traces being written, if true; when false, the new traces will be
2741 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002742 * @param firstPids of dalvik VM processes to dump stack traces for first
2743 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002744 * @return file containing stack traces, or null if no dump file is configured
2745 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002746 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2747 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002748 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2749 if (tracesPath == null || tracesPath.length() == 0) {
2750 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002752
2753 File tracesFile = new File(tracesPath);
2754 try {
2755 File tracesDir = tracesFile.getParentFile();
2756 if (!tracesDir.exists()) tracesFile.mkdirs();
2757 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2758
Christopher Tate6ee412d2010-05-28 12:01:56 -07002759 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002760 tracesFile.createNewFile();
2761 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2762 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002763 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002764 return null;
2765 }
2766
2767 // Use a FileObserver to detect when traces finish writing.
2768 // The order of traces is considered important to maintain for legibility.
2769 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2770 public synchronized void onEvent(int event, String path) { notify(); }
2771 };
2772
2773 try {
2774 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002775
2776 // First collect all of the stacks of the most important pids.
2777 try {
2778 int num = firstPids.size();
2779 for (int i = 0; i < num; i++) {
2780 synchronized (observer) {
2781 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2782 observer.wait(200); // Wait for write-close, give up after 200msec
2783 }
2784 }
2785 } catch (InterruptedException e) {
2786 Log.wtf(TAG, e);
2787 }
2788
2789 // Next measure CPU usage.
2790 if (processStats != null) {
2791 processStats.init();
2792 System.gc();
2793 processStats.update();
2794 try {
2795 synchronized (processStats) {
2796 processStats.wait(500); // measure over 1/2 second.
2797 }
2798 } catch (InterruptedException e) {
2799 }
2800 processStats.update();
2801
2802 // We'll take the stack crawls of just the top apps using CPU.
2803 final int N = processStats.countWorkingStats();
2804 int numProcs = 0;
2805 for (int i=0; i<N && numProcs<5; i++) {
2806 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2807 if (lastPids.indexOfKey(stats.pid) >= 0) {
2808 numProcs++;
2809 try {
2810 synchronized (observer) {
2811 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2812 observer.wait(200); // Wait for write-close, give up after 200msec
2813 }
2814 } catch (InterruptedException e) {
2815 Log.wtf(TAG, e);
2816 }
2817
2818 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002819 }
2820 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002821
2822 return tracesFile;
2823
Dan Egnor42471dd2010-01-07 17:25:22 -08002824 } finally {
2825 observer.stopWatching();
2826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827 }
2828
Jeff Brown4d94a762010-09-23 11:33:28 -07002829 private final class AppNotResponding implements Runnable {
2830 private final ProcessRecord mApp;
2831 private final String mAnnotation;
2832
2833 public AppNotResponding(ProcessRecord app, String annotation) {
2834 mApp = app;
2835 mAnnotation = annotation;
2836 }
2837
2838 @Override
2839 public void run() {
2840 appNotResponding(mApp, null, null, mAnnotation);
2841 }
2842 }
2843
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002844 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2845 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002846 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2847 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2848
Dianne Hackborn287952c2010-09-22 22:34:31 -07002849 if (mController != null) {
2850 try {
2851 // 0 == continue, -1 = kill process immediately
2852 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2853 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2854 } catch (RemoteException e) {
2855 mController = null;
2856 }
2857 }
2858
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002859 long anrTime = SystemClock.uptimeMillis();
2860 if (MONITOR_CPU_USAGE) {
2861 updateCpuStatsNow();
2862 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002863
2864 synchronized (this) {
2865 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2866 if (mShuttingDown) {
2867 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2868 return;
2869 } else if (app.notResponding) {
2870 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2871 return;
2872 } else if (app.crashing) {
2873 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2874 return;
2875 }
2876
2877 // In case we come through here for the same app before completing
2878 // this one, mark as anring now so we will bail out.
2879 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002880
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002881 // Log the ANR to the event log.
2882 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2883 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002884
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002885 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002886 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002887
2888 int parentPid = app.pid;
2889 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002890 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002891
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002892 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002893
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002894 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2895 ProcessRecord r = mLruProcesses.get(i);
2896 if (r != null && r.thread != null) {
2897 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002898 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2899 if (r.persistent) {
2900 firstPids.add(pid);
2901 } else {
2902 lastPids.put(pid, Boolean.TRUE);
2903 }
2904 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 }
2907 }
2908
Dan Egnor42471dd2010-01-07 17:25:22 -08002909 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002910 StringBuilder info = mStringBuilder;
2911 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002912 info.append("ANR in ").append(app.processName);
2913 if (activity != null && activity.shortComponentName != null) {
2914 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002915 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002916 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002917 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002918 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002919 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002920 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002921 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923
Dianne Hackborn287952c2010-09-22 22:34:31 -07002924 final ProcessStats processStats = new ProcessStats(true);
2925
2926 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2927
Dan Egnor42471dd2010-01-07 17:25:22 -08002928 String cpuInfo = null;
2929 if (MONITOR_CPU_USAGE) {
2930 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002931 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002932 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002933 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002934 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002935 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936 }
2937
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002938 info.append(processStats.printCurrentState(anrTime));
2939
Joe Onorato8a9b2202010-02-26 18:56:32 -08002940 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002941 if (tracesFile == null) {
2942 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2943 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2944 }
2945
2946 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2947
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002948 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002949 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002950 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2951 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002952 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002953 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2954 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955 }
2956 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002957 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002958 }
2959 }
2960
Dan Egnor42471dd2010-01-07 17:25:22 -08002961 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2962 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2963 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002964
2965 synchronized (this) {
2966 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002967 Slog.w(TAG, "Killing " + app + ": background ANR");
2968 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
2969 app.processName, app.setAdj, "background ANR");
2970 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002971 return;
2972 }
2973
2974 // Set the app's notResponding state, and look up the errorReportReceiver
2975 makeAppNotRespondingLocked(app,
2976 activity != null ? activity.shortComponentName : null,
2977 annotation != null ? "ANR " + annotation : "ANR",
2978 info.toString());
2979
2980 // Bring up the infamous App Not Responding dialog
2981 Message msg = Message.obtain();
2982 HashMap map = new HashMap();
2983 msg.what = SHOW_NOT_RESPONDING_MSG;
2984 msg.obj = map;
2985 map.put("app", app);
2986 if (activity != null) {
2987 map.put("activity", activity);
2988 }
2989
2990 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08002991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 }
2993
Dianne Hackborn0dad3642010-09-09 21:25:35 -07002994 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
2995 if (!mLaunchWarningShown) {
2996 mLaunchWarningShown = true;
2997 mHandler.post(new Runnable() {
2998 @Override
2999 public void run() {
3000 synchronized (ActivityManagerService.this) {
3001 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3002 d.show();
3003 mHandler.postDelayed(new Runnable() {
3004 @Override
3005 public void run() {
3006 synchronized (ActivityManagerService.this) {
3007 d.dismiss();
3008 mLaunchWarningShown = false;
3009 }
3010 }
3011 }, 4000);
3012 }
3013 }
3014 });
3015 }
3016 }
3017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003018 public boolean clearApplicationUserData(final String packageName,
3019 final IPackageDataObserver observer) {
3020 int uid = Binder.getCallingUid();
3021 int pid = Binder.getCallingPid();
3022 long callingId = Binder.clearCallingIdentity();
3023 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003024 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 int pkgUid = -1;
3026 synchronized(this) {
3027 try {
3028 pkgUid = pm.getPackageUid(packageName);
3029 } catch (RemoteException e) {
3030 }
3031 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003032 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003033 return false;
3034 }
3035 if (uid == pkgUid || checkComponentPermission(
3036 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003037 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003039 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 } else {
3041 throw new SecurityException(pid+" does not have permission:"+
3042 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3043 "for process:"+packageName);
3044 }
3045 }
3046
3047 try {
3048 //clear application user data
3049 pm.clearApplicationUserData(packageName, observer);
3050 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3051 Uri.fromParts("package", packageName, null));
3052 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003053 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3054 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003055 } catch (RemoteException e) {
3056 }
3057 } finally {
3058 Binder.restoreCallingIdentity(callingId);
3059 }
3060 return true;
3061 }
3062
Dianne Hackborn03abb812010-01-04 18:43:19 -08003063 public void killBackgroundProcesses(final String packageName) {
3064 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3065 != PackageManager.PERMISSION_GRANTED &&
3066 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3067 != PackageManager.PERMISSION_GRANTED) {
3068 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 + Binder.getCallingPid()
3070 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003071 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003072 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 throw new SecurityException(msg);
3074 }
3075
3076 long callingId = Binder.clearCallingIdentity();
3077 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003078 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003079 int pkgUid = -1;
3080 synchronized(this) {
3081 try {
3082 pkgUid = pm.getPackageUid(packageName);
3083 } catch (RemoteException e) {
3084 }
3085 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003086 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 return;
3088 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003089 killPackageProcessesLocked(packageName, pkgUid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003090 ProcessList.SECONDARY_SERVER_ADJ, false, true, true, false);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003091 }
3092 } finally {
3093 Binder.restoreCallingIdentity(callingId);
3094 }
3095 }
3096
3097 public void forceStopPackage(final String packageName) {
3098 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3099 != PackageManager.PERMISSION_GRANTED) {
3100 String msg = "Permission Denial: forceStopPackage() from pid="
3101 + Binder.getCallingPid()
3102 + ", uid=" + Binder.getCallingUid()
3103 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003104 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003105 throw new SecurityException(msg);
3106 }
3107
3108 long callingId = Binder.clearCallingIdentity();
3109 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003110 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003111 int pkgUid = -1;
3112 synchronized(this) {
3113 try {
3114 pkgUid = pm.getPackageUid(packageName);
3115 } catch (RemoteException e) {
3116 }
3117 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003118 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003119 return;
3120 }
3121 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003122 try {
3123 pm.setPackageStoppedState(packageName, true);
3124 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003125 } catch (IllegalArgumentException e) {
3126 Slog.w(TAG, "Failed trying to unstop package "
3127 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003129 }
3130 } finally {
3131 Binder.restoreCallingIdentity(callingId);
3132 }
3133 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003134
3135 /*
3136 * The pkg name and uid have to be specified.
3137 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3138 */
3139 public void killApplicationWithUid(String pkg, int uid) {
3140 if (pkg == null) {
3141 return;
3142 }
3143 // Make sure the uid is valid.
3144 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003145 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003146 return;
3147 }
3148 int callerUid = Binder.getCallingUid();
3149 // Only the system server can kill an application
3150 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003151 // Post an aysnc message to kill the application
3152 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3153 msg.arg1 = uid;
3154 msg.arg2 = 0;
3155 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003156 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003157 } else {
3158 throw new SecurityException(callerUid + " cannot kill pkg: " +
3159 pkg);
3160 }
3161 }
3162
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003163 public void closeSystemDialogs(String reason) {
3164 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003165 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003166 if (reason != null) {
3167 intent.putExtra("reason", reason);
3168 }
3169
3170 final int uid = Binder.getCallingUid();
3171 final long origId = Binder.clearCallingIdentity();
3172 synchronized (this) {
3173 int i = mWatchers.beginBroadcast();
3174 while (i > 0) {
3175 i--;
3176 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3177 if (w != null) {
3178 try {
3179 w.closingSystemDialogs(reason);
3180 } catch (RemoteException e) {
3181 }
3182 }
3183 }
3184 mWatchers.finishBroadcast();
3185
Dianne Hackbornffa42482009-09-23 22:20:11 -07003186 mWindowManager.closeSystemDialogs(reason);
3187
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003188 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3189 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003190 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003191 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003192 Activity.RESULT_CANCELED, null, "close-sys");
3193 }
3194 }
3195
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003196 broadcastIntentLocked(null, null, intent, null,
3197 null, 0, null, null, null, false, false, -1, uid);
3198 }
3199 Binder.restoreCallingIdentity(origId);
3200 }
3201
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003202 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003203 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003204 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3205 for (int i=pids.length-1; i>=0; i--) {
3206 infos[i] = new Debug.MemoryInfo();
3207 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003208 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003209 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003210 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003211
Dianne Hackbornb437e092011-08-05 17:50:29 -07003212 public long[] getProcessPss(int[] pids) throws RemoteException {
3213 long[] pss = new long[pids.length];
3214 for (int i=pids.length-1; i>=0; i--) {
3215 pss[i] = Debug.getPss(pids[i]);
3216 }
3217 return pss;
3218 }
3219
Christopher Tate5e1ab332009-09-01 20:32:49 -07003220 public void killApplicationProcess(String processName, int uid) {
3221 if (processName == null) {
3222 return;
3223 }
3224
3225 int callerUid = Binder.getCallingUid();
3226 // Only the system server can kill an application
3227 if (callerUid == Process.SYSTEM_UID) {
3228 synchronized (this) {
3229 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003230 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003231 try {
3232 app.thread.scheduleSuicide();
3233 } catch (RemoteException e) {
3234 // If the other end already died, then our work here is done.
3235 }
3236 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003237 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003238 + processName + " / " + uid);
3239 }
3240 }
3241 } else {
3242 throw new SecurityException(callerUid + " cannot kill app process: " +
3243 processName);
3244 }
3245 }
3246
Dianne Hackborn03abb812010-01-04 18:43:19 -08003247 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003248 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003249 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3250 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003251 if (!mProcessesReady) {
3252 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003254 intent.putExtra(Intent.EXTRA_UID, uid);
3255 broadcastIntentLocked(null, null, intent,
3256 null, null, 0, null, null, null,
3257 false, false, MY_PID, Process.SYSTEM_UID);
3258 }
3259
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003260 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003261 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3262 boolean evenPersistent) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003263 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003264
Dianne Hackborn03abb812010-01-04 18:43:19 -08003265 // Remove all processes this package may have touched: all with the
3266 // same UID (except for the system or root user), and all whose name
3267 // matches the package name.
3268 final String procNamePrefix = packageName + ":";
3269 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3270 final int NA = apps.size();
3271 for (int ia=0; ia<NA; ia++) {
3272 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003273 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003274 // we don't kill persistent processes
3275 continue;
3276 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003277 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003278 if (doit) {
3279 procs.add(app);
3280 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003281 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3282 || app.processName.equals(packageName)
3283 || app.processName.startsWith(procNamePrefix)) {
3284 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003285 if (!doit) {
3286 return true;
3287 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003288 app.removed = true;
3289 procs.add(app);
3290 }
3291 }
3292 }
3293 }
3294
3295 int N = procs.size();
3296 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003297 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003298 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003299 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003300 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003301
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003302 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003303 boolean callerWillRestart, boolean purgeCache, boolean doit,
3304 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003305 int i;
3306 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003308 if (uid < 0) {
3309 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003310 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 } catch (RemoteException e) {
3312 }
3313 }
3314
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003315 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003316 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003317
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003318 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3319 while (badApps.hasNext()) {
3320 SparseArray<Long> ba = badApps.next();
3321 if (ba.get(uid) != null) {
3322 badApps.remove();
3323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 }
3325 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003326
3327 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Christopher Tate3dacd842011-08-19 14:56:15 -07003328 callerWillRestart, false, doit, evenPersistent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003330 TaskRecord lastTask = null;
3331 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003332 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003333 final boolean samePackage = r.packageName.equals(name);
3334 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003335 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003336 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003337 if (r.finishing) {
3338 // If this activity is just finishing, then it is not
3339 // interesting as far as something to stop.
3340 continue;
3341 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003342 return true;
3343 }
3344 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003345 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003346 if (samePackage) {
3347 if (r.app != null) {
3348 r.app.removed = true;
3349 }
3350 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003351 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003352 lastTask = r.task;
3353 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3354 null, "force-stop")) {
3355 i--;
3356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003357 }
3358 }
3359
3360 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3361 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003362 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003363 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003364 if (!doit) {
3365 return true;
3366 }
3367 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003368 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003369 if (service.app != null) {
3370 service.app.removed = true;
3371 }
3372 service.app = null;
3373 services.add(service);
3374 }
3375 }
3376
3377 N = services.size();
3378 for (i=0; i<N; i++) {
3379 bringDownServiceLocked(services.get(i), true);
3380 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003381
3382 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3383 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3384 if (provider.info.packageName.equals(name)
3385 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3386 if (!doit) {
3387 return true;
3388 }
3389 didSomething = true;
3390 providers.add(provider);
3391 }
3392 }
3393
3394 N = providers.size();
3395 for (i=0; i<N; i++) {
3396 removeDyingProviderLocked(null, providers.get(i));
3397 }
3398
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003399 if (doit) {
3400 if (purgeCache) {
3401 AttributeCache ac = AttributeCache.instance();
3402 if (ac != null) {
3403 ac.removePackage(name);
3404 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003405 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003406 mMainStack.resumeTopActivityLocked(null);
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003407 mMainStack.scheduleIdleLocked();
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003408 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003409
3410 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003411 }
3412
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003413 private final boolean removeProcessLocked(ProcessRecord app,
3414 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003415 final String name = app.processName;
3416 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003417 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003418 TAG, "Force removing process " + app + " (" + name
3419 + "/" + uid + ")");
3420
3421 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003422 if (mHeavyWeightProcess == app) {
3423 mHeavyWeightProcess = null;
3424 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3425 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003426 boolean needRestart = false;
3427 if (app.pid > 0 && app.pid != MY_PID) {
3428 int pid = app.pid;
3429 synchronized (mPidsSelfLocked) {
3430 mPidsSelfLocked.remove(pid);
3431 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3432 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003433 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003434 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 Process.killProcess(pid);
3436
3437 if (app.persistent) {
3438 if (!callerWillRestart) {
3439 addAppLocked(app.info);
3440 } else {
3441 needRestart = true;
3442 }
3443 }
3444 } else {
3445 mRemovedProcesses.add(app);
3446 }
3447
3448 return needRestart;
3449 }
3450
3451 private final void processStartTimedOutLocked(ProcessRecord app) {
3452 final int pid = app.pid;
3453 boolean gone = false;
3454 synchronized (mPidsSelfLocked) {
3455 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3456 if (knownApp != null && knownApp.thread == null) {
3457 mPidsSelfLocked.remove(pid);
3458 gone = true;
3459 }
3460 }
3461
3462 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003463 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003464 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003465 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003466 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003467 if (mHeavyWeightProcess == app) {
3468 mHeavyWeightProcess = null;
3469 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3470 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003471 // Take care of any launching providers waiting for this process.
3472 checkAppInLaunchingProvidersLocked(app, true);
3473 // Take care of any services that are waiting for the process.
3474 for (int i=0; i<mPendingServices.size(); i++) {
3475 ServiceRecord sr = mPendingServices.get(i);
3476 if (app.info.uid == sr.appInfo.uid
3477 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003478 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003479 mPendingServices.remove(i);
3480 i--;
3481 bringDownServiceLocked(sr, true);
3482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003483 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003484 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3485 app.processName, app.setAdj, "start timeout");
3486 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003487 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003488 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003489 try {
3490 IBackupManager bm = IBackupManager.Stub.asInterface(
3491 ServiceManager.getService(Context.BACKUP_SERVICE));
3492 bm.agentDisconnected(app.info.packageName);
3493 } catch (RemoteException e) {
3494 // Can't happen; the backup manager is local
3495 }
3496 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003497 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003498 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003499 mPendingBroadcast.state = BroadcastRecord.IDLE;
3500 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003501 mPendingBroadcast = null;
3502 scheduleBroadcastsLocked();
3503 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003504 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003505 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003506 }
3507 }
3508
3509 private final boolean attachApplicationLocked(IApplicationThread thread,
3510 int pid) {
3511
3512 // Find the application record that is being attached... either via
3513 // the pid if we are running in multiple processes, or just pull the
3514 // next app record if we are emulating process with anonymous threads.
3515 ProcessRecord app;
3516 if (pid != MY_PID && pid >= 0) {
3517 synchronized (mPidsSelfLocked) {
3518 app = mPidsSelfLocked.get(pid);
3519 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003520 } else {
3521 app = null;
3522 }
3523
3524 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003525 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003526 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003527 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003528 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003529 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003530 } else {
3531 try {
3532 thread.scheduleExit();
3533 } catch (Exception e) {
3534 // Ignore exceptions.
3535 }
3536 }
3537 return false;
3538 }
3539
3540 // If this application record is still attached to a previous
3541 // process, clean it up now.
3542 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003543 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 }
3545
3546 // Tell the process all about itself.
3547
Joe Onorato8a9b2202010-02-26 18:56:32 -08003548 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003549 TAG, "Binding process pid " + pid + " to record " + app);
3550
3551 String processName = app.processName;
3552 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003553 AppDeathRecipient adr = new AppDeathRecipient(
3554 app, pid, thread);
3555 thread.asBinder().linkToDeath(adr, 0);
3556 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003557 } catch (RemoteException e) {
3558 app.resetPackageList();
3559 startProcessLocked(app, "link fail", processName);
3560 return false;
3561 }
3562
Doug Zongker2bec3d42009-12-04 12:52:44 -08003563 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003564
3565 app.thread = thread;
3566 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003567 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3568 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003569 app.forcingToForeground = null;
3570 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003571 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572 app.debugging = false;
3573
3574 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3575
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003576 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003577 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003578
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003579 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003580 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003581 }
3582
Joe Onorato8a9b2202010-02-26 18:56:32 -08003583 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003584 TAG, "New app record " + app
3585 + " thread=" + thread.asBinder() + " pid=" + pid);
3586 try {
3587 int testMode = IApplicationThread.DEBUG_OFF;
3588 if (mDebugApp != null && mDebugApp.equals(processName)) {
3589 testMode = mWaitForDebugger
3590 ? IApplicationThread.DEBUG_WAIT
3591 : IApplicationThread.DEBUG_ON;
3592 app.debugging = true;
3593 if (mDebugTransient) {
3594 mDebugApp = mOrigDebugApp;
3595 mWaitForDebugger = mOrigWaitForDebugger;
3596 }
3597 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003598 String profileFile = app.instrumentationProfileFile;
3599 ParcelFileDescriptor profileFd = null;
3600 boolean profileAutoStop = false;
3601 if (mProfileApp != null && mProfileApp.equals(processName)) {
3602 mProfileProc = app;
3603 profileFile = mProfileFile;
3604 profileFd = mProfileFd;
3605 profileAutoStop = mAutoStopProfiler;
3606 }
3607
Christopher Tate181fafa2009-05-14 11:12:14 -07003608 // If the app is being launched for restore or full backup, set it up specially
3609 boolean isRestrictedBackupMode = false;
3610 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3611 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003612 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003613 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3614 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003615
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003616 ensurePackageDexOpt(app.instrumentationInfo != null
3617 ? app.instrumentationInfo.packageName
3618 : app.info.packageName);
3619 if (app.instrumentationClass != null) {
3620 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003621 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003622 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003623 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003624 ApplicationInfo appInfo = app.instrumentationInfo != null
3625 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003626 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003627 if (profileFd != null) {
3628 profileFd = profileFd.dup();
3629 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003630 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003631 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003633 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003634 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003635 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003636 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003637 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 } catch (Exception e) {
3639 // todo: Yikes! What should we do? For now we will try to
3640 // start another process, but that could easily get us in
3641 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003642 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003643
3644 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003645 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003646 startProcessLocked(app, "bind fail", processName);
3647 return false;
3648 }
3649
3650 // Remove this record from the list of starting applications.
3651 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003652 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3653 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003654 mProcessesOnHold.remove(app);
3655
3656 boolean badApp = false;
3657 boolean didSomething = false;
3658
3659 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003660 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003661 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003662 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3663 && processName.equals(hr.processName)) {
3664 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003665 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 didSomething = true;
3667 }
3668 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003669 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 + hr.intent.getComponent().flattenToShortString(), e);
3671 badApp = true;
3672 }
3673 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003674 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003675 }
3676 }
3677
3678 // Find any services that should be running in this process...
3679 if (!badApp && mPendingServices.size() > 0) {
3680 ServiceRecord sr = null;
3681 try {
3682 for (int i=0; i<mPendingServices.size(); i++) {
3683 sr = mPendingServices.get(i);
3684 if (app.info.uid != sr.appInfo.uid
3685 || !processName.equals(sr.processName)) {
3686 continue;
3687 }
3688
3689 mPendingServices.remove(i);
3690 i--;
3691 realStartServiceLocked(sr, app);
3692 didSomething = true;
3693 }
3694 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003695 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003696 + sr.shortName, e);
3697 badApp = true;
3698 }
3699 }
3700
3701 // Check if the next broadcast receiver is in this process...
3702 BroadcastRecord br = mPendingBroadcast;
3703 if (!badApp && br != null && br.curApp == app) {
3704 try {
3705 mPendingBroadcast = null;
3706 processCurBroadcastLocked(br, app);
3707 didSomething = true;
3708 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003709 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 + br.curComponent.flattenToShortString(), e);
3711 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003712 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3714 br.resultExtras, br.resultAbort, true);
3715 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003716 // We need to reset the state if we fails to start the receiver.
3717 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 }
3719 }
3720
Christopher Tate181fafa2009-05-14 11:12:14 -07003721 // Check whether the next backup agent is in this process...
3722 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003723 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003724 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003725 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003726 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3727 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3728 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003729 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003730 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003731 e.printStackTrace();
3732 }
3733 }
3734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003735 if (badApp) {
3736 // todo: Also need to kill application to deal with all
3737 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003738 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003739 return false;
3740 }
3741
3742 if (!didSomething) {
3743 updateOomAdjLocked();
3744 }
3745
3746 return true;
3747 }
3748
3749 public final void attachApplication(IApplicationThread thread) {
3750 synchronized (this) {
3751 int callingPid = Binder.getCallingPid();
3752 final long origId = Binder.clearCallingIdentity();
3753 attachApplicationLocked(thread, callingPid);
3754 Binder.restoreCallingIdentity(origId);
3755 }
3756 }
3757
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003758 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003759 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003760 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3761 if (stopProfiling) {
3762 synchronized (this) {
3763 if (mProfileProc == r.app) {
3764 if (mProfileFd != null) {
3765 try {
3766 mProfileFd.close();
3767 } catch (IOException e) {
3768 }
3769 clearProfilerLocked();
3770 }
3771 }
3772 }
3773 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003774 Binder.restoreCallingIdentity(origId);
3775 }
3776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003777 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003778 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003779 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003780 mWindowManager.enableScreenAfterBoot();
3781 }
3782
Dianne Hackborn661cd522011-08-22 00:26:20 -07003783 public void showBootMessage(final CharSequence msg, final boolean always) {
3784 mWindowManager.showBootMessage(msg, always);
3785 }
3786
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003787 public void dismissKeyguardOnNextActivity() {
3788 synchronized (this) {
3789 mMainStack.dismissKeyguardOnNextActivityLocked();
3790 }
3791 }
3792
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003793 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003794 IntentFilter pkgFilter = new IntentFilter();
3795 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3796 pkgFilter.addDataScheme("package");
3797 mContext.registerReceiver(new BroadcastReceiver() {
3798 @Override
3799 public void onReceive(Context context, Intent intent) {
3800 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3801 if (pkgs != null) {
3802 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003803 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003804 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003805 setResultCode(Activity.RESULT_OK);
3806 return;
3807 }
3808 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003809 }
3810 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003811 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003812 }, pkgFilter);
3813
3814 synchronized (this) {
3815 // Ensure that any processes we had put on hold are now started
3816 // up.
3817 final int NP = mProcessesOnHold.size();
3818 if (NP > 0) {
3819 ArrayList<ProcessRecord> procs =
3820 new ArrayList<ProcessRecord>(mProcessesOnHold);
3821 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003822 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3823 + procs.get(ip));
3824 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003825 }
3826 }
3827
3828 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003829 // Start looking for apps that are abusing wake locks.
3830 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003831 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003832 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003833 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003834 broadcastIntentLocked(null, null,
3835 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3836 null, null, 0, null, null,
3837 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3838 false, false, MY_PID, Process.SYSTEM_UID);
3839 }
3840 }
3841 }
3842
3843 final void ensureBootCompleted() {
3844 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003845 boolean enableScreen;
3846 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003847 booting = mBooting;
3848 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003849 enableScreen = !mBooted;
3850 mBooted = true;
3851 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003852
3853 if (booting) {
3854 finishBooting();
3855 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003856
3857 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003858 enableScreenAfterBoot();
3859 }
3860 }
3861
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003862 public final void activityPaused(IBinder token) {
3863 final long origId = Binder.clearCallingIdentity();
3864 mMainStack.activityPaused(token, false);
3865 Binder.restoreCallingIdentity(origId);
3866 }
3867
3868 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3869 CharSequence description) {
3870 if (localLOGV) Slog.v(
3871 TAG, "Activity stopped: token=" + token);
3872
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003873 // Refuse possible leaked file descriptors
3874 if (icicle != null && icicle.hasFileDescriptors()) {
3875 throw new IllegalArgumentException("File descriptors passed in Bundle");
3876 }
3877
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003878 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879
3880 final long origId = Binder.clearCallingIdentity();
3881
3882 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003883 r = mMainStack.isInStackLocked(token);
3884 if (r != null) {
3885 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 }
3887 }
3888
3889 if (r != null) {
3890 sendPendingThumbnail(r, null, null, null, false);
3891 }
3892
3893 trimApplications();
3894
3895 Binder.restoreCallingIdentity(origId);
3896 }
3897
3898 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003899 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003900 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003901 }
3902
3903 public String getCallingPackage(IBinder token) {
3904 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003905 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003906 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003907 }
3908 }
3909
3910 public ComponentName getCallingActivity(IBinder token) {
3911 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003912 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003913 return r != null ? r.intent.getComponent() : null;
3914 }
3915 }
3916
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003917 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003918 ActivityRecord r = mMainStack.isInStackLocked(token);
3919 if (r == null) {
3920 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003921 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003922 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003923 }
3924
3925 public ComponentName getActivityClassForToken(IBinder token) {
3926 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003927 ActivityRecord r = mMainStack.isInStackLocked(token);
3928 if (r == null) {
3929 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003930 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003931 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003932 }
3933 }
3934
3935 public String getPackageForToken(IBinder token) {
3936 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003937 ActivityRecord r = mMainStack.isInStackLocked(token);
3938 if (r == null) {
3939 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003940 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003941 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 }
3943 }
3944
3945 public IIntentSender getIntentSender(int type,
3946 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003947 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003948 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003949 if (intents != null) {
3950 if (intents.length < 1) {
3951 throw new IllegalArgumentException("Intents array length must be >= 1");
3952 }
3953 for (int i=0; i<intents.length; i++) {
3954 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003955 if (intent != null) {
3956 if (intent.hasFileDescriptors()) {
3957 throw new IllegalArgumentException("File descriptors passed in Intent");
3958 }
3959 if (type == INTENT_SENDER_BROADCAST &&
3960 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3961 throw new IllegalArgumentException(
3962 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3963 }
3964 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003965 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003966 }
3967 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003968 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003969 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003970 }
3971 }
3972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003973 synchronized(this) {
3974 int callingUid = Binder.getCallingUid();
3975 try {
Jeff Brown10e89712011-07-08 18:52:57 -07003976 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003977 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003978 .getPackageUid(packageName);
3979 if (uid != Binder.getCallingUid()) {
3980 String msg = "Permission Denial: getIntentSender() from pid="
3981 + Binder.getCallingPid()
3982 + ", uid=" + Binder.getCallingUid()
3983 + ", (need uid=" + uid + ")"
3984 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003985 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003986 throw new SecurityException(msg);
3987 }
3988 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003989
3990 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003991 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003993 } catch (RemoteException e) {
3994 throw new SecurityException(e);
3995 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003996 }
3997 }
3998
3999 IIntentSender getIntentSenderLocked(int type,
4000 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004001 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004002 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004003 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004004 activity = mMainStack.isInStackLocked(token);
4005 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004006 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004007 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004008 if (activity.finishing) {
4009 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004010 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004011 }
4012
4013 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4014 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4015 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4016 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4017 |PendingIntent.FLAG_UPDATE_CURRENT);
4018
4019 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4020 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004021 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004022 WeakReference<PendingIntentRecord> ref;
4023 ref = mIntentSenderRecords.get(key);
4024 PendingIntentRecord rec = ref != null ? ref.get() : null;
4025 if (rec != null) {
4026 if (!cancelCurrent) {
4027 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004028 if (rec.key.requestIntent != null) {
4029 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4030 }
4031 if (intents != null) {
4032 intents[intents.length-1] = rec.key.requestIntent;
4033 rec.key.allIntents = intents;
4034 rec.key.allResolvedTypes = resolvedTypes;
4035 } else {
4036 rec.key.allIntents = null;
4037 rec.key.allResolvedTypes = null;
4038 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004039 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004040 return rec;
4041 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004042 rec.canceled = true;
4043 mIntentSenderRecords.remove(key);
4044 }
4045 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004046 return rec;
4047 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004048 rec = new PendingIntentRecord(this, key, callingUid);
4049 mIntentSenderRecords.put(key, rec.ref);
4050 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4051 if (activity.pendingResults == null) {
4052 activity.pendingResults
4053 = new HashSet<WeakReference<PendingIntentRecord>>();
4054 }
4055 activity.pendingResults.add(rec.ref);
4056 }
4057 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004058 }
4059
4060 public void cancelIntentSender(IIntentSender sender) {
4061 if (!(sender instanceof PendingIntentRecord)) {
4062 return;
4063 }
4064 synchronized(this) {
4065 PendingIntentRecord rec = (PendingIntentRecord)sender;
4066 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004067 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004068 .getPackageUid(rec.key.packageName);
4069 if (uid != Binder.getCallingUid()) {
4070 String msg = "Permission Denial: cancelIntentSender() from pid="
4071 + Binder.getCallingPid()
4072 + ", uid=" + Binder.getCallingUid()
4073 + " is not allowed to cancel packges "
4074 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004075 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004076 throw new SecurityException(msg);
4077 }
4078 } catch (RemoteException e) {
4079 throw new SecurityException(e);
4080 }
4081 cancelIntentSenderLocked(rec, true);
4082 }
4083 }
4084
4085 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4086 rec.canceled = true;
4087 mIntentSenderRecords.remove(rec.key);
4088 if (cleanActivity && rec.key.activity != null) {
4089 rec.key.activity.pendingResults.remove(rec.ref);
4090 }
4091 }
4092
4093 public String getPackageForIntentSender(IIntentSender pendingResult) {
4094 if (!(pendingResult instanceof PendingIntentRecord)) {
4095 return null;
4096 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004097 try {
4098 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4099 return res.key.packageName;
4100 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004101 }
4102 return null;
4103 }
4104
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004105 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4106 if (!(pendingResult instanceof PendingIntentRecord)) {
4107 return false;
4108 }
4109 try {
4110 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4111 if (res.key.allIntents == null) {
4112 return false;
4113 }
4114 for (int i=0; i<res.key.allIntents.length; i++) {
4115 Intent intent = res.key.allIntents[i];
4116 if (intent.getPackage() != null && intent.getComponent() != null) {
4117 return false;
4118 }
4119 }
4120 return true;
4121 } catch (ClassCastException e) {
4122 }
4123 return false;
4124 }
4125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004126 public void setProcessLimit(int max) {
4127 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4128 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004129 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004130 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004131 mProcessLimitOverride = max;
4132 }
4133 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004134 }
4135
4136 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004137 synchronized (this) {
4138 return mProcessLimitOverride;
4139 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004140 }
4141
4142 void foregroundTokenDied(ForegroundToken token) {
4143 synchronized (ActivityManagerService.this) {
4144 synchronized (mPidsSelfLocked) {
4145 ForegroundToken cur
4146 = mForegroundProcesses.get(token.pid);
4147 if (cur != token) {
4148 return;
4149 }
4150 mForegroundProcesses.remove(token.pid);
4151 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4152 if (pr == null) {
4153 return;
4154 }
4155 pr.forcingToForeground = null;
4156 pr.foregroundServices = false;
4157 }
4158 updateOomAdjLocked();
4159 }
4160 }
4161
4162 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4163 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4164 "setProcessForeground()");
4165 synchronized(this) {
4166 boolean changed = false;
4167
4168 synchronized (mPidsSelfLocked) {
4169 ProcessRecord pr = mPidsSelfLocked.get(pid);
4170 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004171 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004172 return;
4173 }
4174 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4175 if (oldToken != null) {
4176 oldToken.token.unlinkToDeath(oldToken, 0);
4177 mForegroundProcesses.remove(pid);
4178 pr.forcingToForeground = null;
4179 changed = true;
4180 }
4181 if (isForeground && token != null) {
4182 ForegroundToken newToken = new ForegroundToken() {
4183 public void binderDied() {
4184 foregroundTokenDied(this);
4185 }
4186 };
4187 newToken.pid = pid;
4188 newToken.token = token;
4189 try {
4190 token.linkToDeath(newToken, 0);
4191 mForegroundProcesses.put(pid, newToken);
4192 pr.forcingToForeground = token;
4193 changed = true;
4194 } catch (RemoteException e) {
4195 // If the process died while doing this, we will later
4196 // do the cleanup with the process death link.
4197 }
4198 }
4199 }
4200
4201 if (changed) {
4202 updateOomAdjLocked();
4203 }
4204 }
4205 }
4206
4207 // =========================================================
4208 // PERMISSIONS
4209 // =========================================================
4210
4211 static class PermissionController extends IPermissionController.Stub {
4212 ActivityManagerService mActivityManagerService;
4213 PermissionController(ActivityManagerService activityManagerService) {
4214 mActivityManagerService = activityManagerService;
4215 }
4216
4217 public boolean checkPermission(String permission, int pid, int uid) {
4218 return mActivityManagerService.checkPermission(permission, pid,
4219 uid) == PackageManager.PERMISSION_GRANTED;
4220 }
4221 }
4222
4223 /**
4224 * This can be called with or without the global lock held.
4225 */
4226 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004227 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004228 // We might be performing an operation on behalf of an indirect binder
4229 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4230 // client identity accordingly before proceeding.
4231 Identity tlsIdentity = sCallerIdentity.get();
4232 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004233 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004234 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4235 uid = tlsIdentity.uid;
4236 pid = tlsIdentity.pid;
4237 }
4238
4239 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004240 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004241 return PackageManager.PERMISSION_GRANTED;
4242 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004243 // If there is a uid that owns whatever is being accessed, it has
4244 // blanket access to it regardless of the permissions it requires.
4245 if (owningUid >= 0 && uid == owningUid) {
4246 return PackageManager.PERMISSION_GRANTED;
4247 }
4248 // If the target is not exported, then nobody else can get to it.
4249 if (!exported) {
4250 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004251 return PackageManager.PERMISSION_DENIED;
4252 }
4253 if (permission == null) {
4254 return PackageManager.PERMISSION_GRANTED;
4255 }
4256 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004257 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004258 .checkUidPermission(permission, uid);
4259 } catch (RemoteException e) {
4260 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004261 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004262 }
4263 return PackageManager.PERMISSION_DENIED;
4264 }
4265
4266 /**
4267 * As the only public entry point for permissions checking, this method
4268 * can enforce the semantic that requesting a check on a null global
4269 * permission is automatically denied. (Internally a null permission
4270 * string is used when calling {@link #checkComponentPermission} in cases
4271 * when only uid-based security is needed.)
4272 *
4273 * This can be called with or without the global lock held.
4274 */
4275 public int checkPermission(String permission, int pid, int uid) {
4276 if (permission == null) {
4277 return PackageManager.PERMISSION_DENIED;
4278 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004279 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004280 }
4281
4282 /**
4283 * Binder IPC calls go through the public entry point.
4284 * This can be called with or without the global lock held.
4285 */
4286 int checkCallingPermission(String permission) {
4287 return checkPermission(permission,
4288 Binder.getCallingPid(),
4289 Binder.getCallingUid());
4290 }
4291
4292 /**
4293 * This can be called with or without the global lock held.
4294 */
4295 void enforceCallingPermission(String permission, String func) {
4296 if (checkCallingPermission(permission)
4297 == PackageManager.PERMISSION_GRANTED) {
4298 return;
4299 }
4300
4301 String msg = "Permission Denial: " + func + " from pid="
4302 + Binder.getCallingPid()
4303 + ", uid=" + Binder.getCallingUid()
4304 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004305 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 throw new SecurityException(msg);
4307 }
4308
4309 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004310 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4311 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4312 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4313 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4314 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004315 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004316 // Is the component private from the target uid?
4317 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4318
4319 // Acceptable if the there is no read permission needed from the
4320 // target or the target is holding the read permission.
4321 if (!readPerm) {
4322 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004323 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004324 == PackageManager.PERMISSION_GRANTED)) {
4325 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004326 }
4327 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004328
4329 // Acceptable if the there is no write permission needed from the
4330 // target or the target is holding the read permission.
4331 if (!writePerm) {
4332 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004333 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004334 == PackageManager.PERMISSION_GRANTED)) {
4335 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004336 }
4337 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004338
4339 // Acceptable if there is a path permission matching the URI that
4340 // the target holds the permission on.
4341 PathPermission[] pps = pi.pathPermissions;
4342 if (pps != null && (!readPerm || !writePerm)) {
4343 final String path = uri.getPath();
4344 int i = pps.length;
4345 while (i > 0 && (!readPerm || !writePerm)) {
4346 i--;
4347 PathPermission pp = pps[i];
4348 if (!readPerm) {
4349 final String pprperm = pp.getReadPermission();
4350 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4351 + pprperm + " for " + pp.getPath()
4352 + ": match=" + pp.match(path)
4353 + " check=" + pm.checkUidPermission(pprperm, uid));
4354 if (pprperm != null && pp.match(path) &&
4355 (pm.checkUidPermission(pprperm, uid)
4356 == PackageManager.PERMISSION_GRANTED)) {
4357 readPerm = true;
4358 }
4359 }
4360 if (!writePerm) {
4361 final String ppwperm = pp.getWritePermission();
4362 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4363 + ppwperm + " for " + pp.getPath()
4364 + ": match=" + pp.match(path)
4365 + " check=" + pm.checkUidPermission(ppwperm, uid));
4366 if (ppwperm != null && pp.match(path) &&
4367 (pm.checkUidPermission(ppwperm, uid)
4368 == PackageManager.PERMISSION_GRANTED)) {
4369 writePerm = true;
4370 }
4371 }
4372 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004374 } catch (RemoteException e) {
4375 return false;
4376 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004377
4378 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004379 }
4380
4381 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4382 int modeFlags) {
4383 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004384 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004385 return true;
4386 }
4387 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4388 if (perms == null) return false;
4389 UriPermission perm = perms.get(uri);
4390 if (perm == null) return false;
4391 return (modeFlags&perm.modeFlags) == modeFlags;
4392 }
4393
4394 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4395 // Another redirected-binder-call permissions check as in
4396 // {@link checkComponentPermission}.
4397 Identity tlsIdentity = sCallerIdentity.get();
4398 if (tlsIdentity != null) {
4399 uid = tlsIdentity.uid;
4400 pid = tlsIdentity.pid;
4401 }
4402
4403 // Our own process gets to do everything.
4404 if (pid == MY_PID) {
4405 return PackageManager.PERMISSION_GRANTED;
4406 }
4407 synchronized(this) {
4408 return checkUriPermissionLocked(uri, uid, modeFlags)
4409 ? PackageManager.PERMISSION_GRANTED
4410 : PackageManager.PERMISSION_DENIED;
4411 }
4412 }
4413
Dianne Hackborn39792d22010-08-19 18:01:52 -07004414 /**
4415 * Check if the targetPkg can be granted permission to access uri by
4416 * the callingUid using the given modeFlags. Throws a security exception
4417 * if callingUid is not allowed to do this. Returns the uid of the target
4418 * if the URI permission grant should be performed; returns -1 if it is not
4419 * needed (for example targetPkg already has permission to access the URI).
4420 */
4421 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4422 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004423 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4424 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4425 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004426 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004427 }
4428
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004429 if (targetPkg != null) {
4430 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4431 "Checking grant " + targetPkg + " permission to " + uri);
4432 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004433
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004434 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004435
4436 // If this is not a content: uri, we can't do anything with it.
4437 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004438 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004439 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004440 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004441 }
4442
4443 String name = uri.getAuthority();
4444 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004445 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004446 if (cpr != null) {
4447 pi = cpr.info;
4448 } else {
4449 try {
4450 pi = pm.resolveContentProvider(name,
4451 PackageManager.GET_URI_PERMISSION_PATTERNS);
4452 } catch (RemoteException ex) {
4453 }
4454 }
4455 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004456 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004457 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004458 }
4459
4460 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004461 if (targetPkg != null) {
4462 try {
4463 targetUid = pm.getPackageUid(targetPkg);
4464 if (targetUid < 0) {
4465 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4466 "Can't grant URI permission no uid for: " + targetPkg);
4467 return -1;
4468 }
4469 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004470 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004471 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004472 } else {
4473 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004474 }
4475
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004476 if (targetUid >= 0) {
4477 // First... does the target actually need this permission?
4478 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4479 // No need to grant the target this permission.
4480 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4481 "Target " + targetPkg + " already has full permission to " + uri);
4482 return -1;
4483 }
4484 } else {
4485 // First... there is no target package, so can anyone access it?
4486 boolean allowed = pi.exported;
4487 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4488 if (pi.readPermission != null) {
4489 allowed = false;
4490 }
4491 }
4492 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4493 if (pi.writePermission != null) {
4494 allowed = false;
4495 }
4496 }
4497 if (allowed) {
4498 return -1;
4499 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004500 }
4501
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004502 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 if (!pi.grantUriPermissions) {
4504 throw new SecurityException("Provider " + pi.packageName
4505 + "/" + pi.name
4506 + " does not allow granting of Uri permissions (uri "
4507 + uri + ")");
4508 }
4509 if (pi.uriPermissionPatterns != null) {
4510 final int N = pi.uriPermissionPatterns.length;
4511 boolean allowed = false;
4512 for (int i=0; i<N; i++) {
4513 if (pi.uriPermissionPatterns[i] != null
4514 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4515 allowed = true;
4516 break;
4517 }
4518 }
4519 if (!allowed) {
4520 throw new SecurityException("Provider " + pi.packageName
4521 + "/" + pi.name
4522 + " does not allow granting of permission to path of Uri "
4523 + uri);
4524 }
4525 }
4526
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004527 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004528 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004529 if (callingUid != Process.myUid()) {
4530 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4531 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4532 throw new SecurityException("Uid " + callingUid
4533 + " does not have permission to uri " + uri);
4534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004535 }
4536 }
4537
Dianne Hackborn39792d22010-08-19 18:01:52 -07004538 return targetUid;
4539 }
4540
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004541 public int checkGrantUriPermission(int callingUid, String targetPkg,
4542 Uri uri, int modeFlags) {
4543 synchronized(this) {
4544 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4545 }
4546 }
4547
Dianne Hackborn39792d22010-08-19 18:01:52 -07004548 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4549 Uri uri, int modeFlags, UriPermissionOwner owner) {
4550 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4551 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4552 if (modeFlags == 0) {
4553 return;
4554 }
4555
4556 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004557 // to the uri, and the target doesn't. Let's now give this to
4558 // the target.
4559
Joe Onorato8a9b2202010-02-26 18:56:32 -08004560 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004561 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004563 HashMap<Uri, UriPermission> targetUris
4564 = mGrantedUriPermissions.get(targetUid);
4565 if (targetUris == null) {
4566 targetUris = new HashMap<Uri, UriPermission>();
4567 mGrantedUriPermissions.put(targetUid, targetUris);
4568 }
4569
4570 UriPermission perm = targetUris.get(uri);
4571 if (perm == null) {
4572 perm = new UriPermission(targetUid, uri);
4573 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004574 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004576 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004577 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004578 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004579 } else {
4580 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4581 perm.readOwners.add(owner);
4582 owner.addReadPermission(perm);
4583 }
4584 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4585 perm.writeOwners.add(owner);
4586 owner.addWritePermission(perm);
4587 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004588 }
4589 }
4590
Dianne Hackborn39792d22010-08-19 18:01:52 -07004591 void grantUriPermissionLocked(int callingUid,
4592 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004593 if (targetPkg == null) {
4594 throw new NullPointerException("targetPkg");
4595 }
4596
Dianne Hackborn39792d22010-08-19 18:01:52 -07004597 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4598 if (targetUid < 0) {
4599 return;
4600 }
4601
4602 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4603 }
4604
4605 /**
4606 * Like checkGrantUriPermissionLocked, but takes an Intent.
4607 */
4608 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4609 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004610 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004611 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004612 + " from " + intent + "; flags=0x"
4613 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4614
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004615 if (targetPkg == null) {
4616 throw new NullPointerException("targetPkg");
4617 }
4618
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004619 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004620 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004621 }
4622 Uri data = intent.getData();
4623 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004624 return -1;
4625 }
4626 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4627 intent.getFlags());
4628 }
4629
4630 /**
4631 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4632 */
4633 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4634 String targetPkg, Intent intent, UriPermissionOwner owner) {
4635 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4636 intent.getFlags(), owner);
4637 }
4638
4639 void grantUriPermissionFromIntentLocked(int callingUid,
4640 String targetPkg, Intent intent, UriPermissionOwner owner) {
4641 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4642 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004643 return;
4644 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004645
4646 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 }
4648
4649 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4650 Uri uri, int modeFlags) {
4651 synchronized(this) {
4652 final ProcessRecord r = getRecordForAppLocked(caller);
4653 if (r == null) {
4654 throw new SecurityException("Unable to find app for caller "
4655 + caller
4656 + " when granting permission to uri " + uri);
4657 }
4658 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004659 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004660 }
4661 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004662 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004663 }
4664
4665 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4666 null);
4667 }
4668 }
4669
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004670 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004671 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4672 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4673 HashMap<Uri, UriPermission> perms
4674 = mGrantedUriPermissions.get(perm.uid);
4675 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004676 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004677 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004678 perms.remove(perm.uri);
4679 if (perms.size() == 0) {
4680 mGrantedUriPermissions.remove(perm.uid);
4681 }
4682 }
4683 }
4684 }
4685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004686 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4687 int modeFlags) {
4688 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4689 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4690 if (modeFlags == 0) {
4691 return;
4692 }
4693
Joe Onorato8a9b2202010-02-26 18:56:32 -08004694 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004695 "Revoking all granted permissions to " + uri);
4696
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004697 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004698
4699 final String authority = uri.getAuthority();
4700 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004701 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004702 if (cpr != null) {
4703 pi = cpr.info;
4704 } else {
4705 try {
4706 pi = pm.resolveContentProvider(authority,
4707 PackageManager.GET_URI_PERMISSION_PATTERNS);
4708 } catch (RemoteException ex) {
4709 }
4710 }
4711 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004712 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004713 return;
4714 }
4715
4716 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004717 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004718 // Right now, if you are not the original owner of the permission,
4719 // you are not allowed to revoke it.
4720 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4721 throw new SecurityException("Uid " + callingUid
4722 + " does not have permission to uri " + uri);
4723 //}
4724 }
4725
4726 // Go through all of the permissions and remove any that match.
4727 final List<String> SEGMENTS = uri.getPathSegments();
4728 if (SEGMENTS != null) {
4729 final int NS = SEGMENTS.size();
4730 int N = mGrantedUriPermissions.size();
4731 for (int i=0; i<N; i++) {
4732 HashMap<Uri, UriPermission> perms
4733 = mGrantedUriPermissions.valueAt(i);
4734 Iterator<UriPermission> it = perms.values().iterator();
4735 toploop:
4736 while (it.hasNext()) {
4737 UriPermission perm = it.next();
4738 Uri targetUri = perm.uri;
4739 if (!authority.equals(targetUri.getAuthority())) {
4740 continue;
4741 }
4742 List<String> targetSegments = targetUri.getPathSegments();
4743 if (targetSegments == null) {
4744 continue;
4745 }
4746 if (targetSegments.size() < NS) {
4747 continue;
4748 }
4749 for (int j=0; j<NS; j++) {
4750 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4751 continue toploop;
4752 }
4753 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004754 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004755 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004756 perm.clearModes(modeFlags);
4757 if (perm.modeFlags == 0) {
4758 it.remove();
4759 }
4760 }
4761 if (perms.size() == 0) {
4762 mGrantedUriPermissions.remove(
4763 mGrantedUriPermissions.keyAt(i));
4764 N--;
4765 i--;
4766 }
4767 }
4768 }
4769 }
4770
4771 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4772 int modeFlags) {
4773 synchronized(this) {
4774 final ProcessRecord r = getRecordForAppLocked(caller);
4775 if (r == null) {
4776 throw new SecurityException("Unable to find app for caller "
4777 + caller
4778 + " when revoking permission to uri " + uri);
4779 }
4780 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004781 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004782 return;
4783 }
4784
4785 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4786 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4787 if (modeFlags == 0) {
4788 return;
4789 }
4790
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004791 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004792
4793 final String authority = uri.getAuthority();
4794 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004795 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004796 if (cpr != null) {
4797 pi = cpr.info;
4798 } else {
4799 try {
4800 pi = pm.resolveContentProvider(authority,
4801 PackageManager.GET_URI_PERMISSION_PATTERNS);
4802 } catch (RemoteException ex) {
4803 }
4804 }
4805 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004806 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004807 return;
4808 }
4809
4810 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4811 }
4812 }
4813
Dianne Hackborn7e269642010-08-25 19:50:20 -07004814 @Override
4815 public IBinder newUriPermissionOwner(String name) {
4816 synchronized(this) {
4817 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4818 return owner.getExternalTokenLocked();
4819 }
4820 }
4821
4822 @Override
4823 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4824 Uri uri, int modeFlags) {
4825 synchronized(this) {
4826 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4827 if (owner == null) {
4828 throw new IllegalArgumentException("Unknown owner: " + token);
4829 }
4830 if (fromUid != Binder.getCallingUid()) {
4831 if (Binder.getCallingUid() != Process.myUid()) {
4832 // Only system code can grant URI permissions on behalf
4833 // of other users.
4834 throw new SecurityException("nice try");
4835 }
4836 }
4837 if (targetPkg == null) {
4838 throw new IllegalArgumentException("null target");
4839 }
4840 if (uri == null) {
4841 throw new IllegalArgumentException("null uri");
4842 }
4843
4844 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4845 }
4846 }
4847
4848 @Override
4849 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4850 synchronized(this) {
4851 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4852 if (owner == null) {
4853 throw new IllegalArgumentException("Unknown owner: " + token);
4854 }
4855
4856 if (uri == null) {
4857 owner.removeUriPermissionsLocked(mode);
4858 } else {
4859 owner.removeUriPermissionLocked(uri, mode);
4860 }
4861 }
4862 }
4863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004864 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4865 synchronized (this) {
4866 ProcessRecord app =
4867 who != null ? getRecordForAppLocked(who) : null;
4868 if (app == null) return;
4869
4870 Message msg = Message.obtain();
4871 msg.what = WAIT_FOR_DEBUGGER_MSG;
4872 msg.obj = app;
4873 msg.arg1 = waiting ? 1 : 0;
4874 mHandler.sendMessage(msg);
4875 }
4876 }
4877
4878 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004879 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4880 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004881 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004882 outInfo.threshold = homeAppMem;
4883 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4884 outInfo.hiddenAppThreshold = hiddenAppMem;
4885 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4886 ProcessList.SECONDARY_SERVER_ADJ);
4887 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4888 ProcessList.VISIBLE_APP_ADJ);
4889 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4890 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004891 }
4892
4893 // =========================================================
4894 // TASK MANAGEMENT
4895 // =========================================================
4896
4897 public List getTasks(int maxNum, int flags,
4898 IThumbnailReceiver receiver) {
4899 ArrayList list = new ArrayList();
4900
4901 PendingThumbnailsRecord pending = null;
4902 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004903 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004904
4905 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004906 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004907 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4908 + ", receiver=" + receiver);
4909
4910 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4911 != PackageManager.PERMISSION_GRANTED) {
4912 if (receiver != null) {
4913 // If the caller wants to wait for pending thumbnails,
4914 // it ain't gonna get them.
4915 try {
4916 receiver.finished();
4917 } catch (RemoteException ex) {
4918 }
4919 }
4920 String msg = "Permission Denial: getTasks() from pid="
4921 + Binder.getCallingPid()
4922 + ", uid=" + Binder.getCallingUid()
4923 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004924 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004925 throw new SecurityException(msg);
4926 }
4927
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004928 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004929 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004930 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004931 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004932 TaskRecord curTask = null;
4933 int numActivities = 0;
4934 int numRunning = 0;
4935 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004936 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004937 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004938 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004939
4940 // Initialize state for next task if needed.
4941 if (top == null ||
4942 (top.state == ActivityState.INITIALIZING
4943 && top.task == r.task)) {
4944 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004945 curTask = r.task;
4946 numActivities = numRunning = 0;
4947 }
4948
4949 // Add 'r' into the current task.
4950 numActivities++;
4951 if (r.app != null && r.app.thread != null) {
4952 numRunning++;
4953 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004954
Joe Onorato8a9b2202010-02-26 18:56:32 -08004955 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004956 TAG, r.intent.getComponent().flattenToShortString()
4957 + ": task=" + r.task);
4958
4959 // If the next one is a different task, generate a new
4960 // TaskInfo entry for what we have.
4961 if (next == null || next.task != curTask) {
4962 ActivityManager.RunningTaskInfo ci
4963 = new ActivityManager.RunningTaskInfo();
4964 ci.id = curTask.taskId;
4965 ci.baseActivity = r.intent.getComponent();
4966 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004967 if (top.thumbHolder != null) {
4968 ci.description = top.thumbHolder.lastDescription;
4969 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004970 ci.numActivities = numActivities;
4971 ci.numRunning = numRunning;
4972 //System.out.println(
4973 // "#" + maxNum + ": " + " descr=" + ci.description);
4974 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004975 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004976 TAG, "State=" + top.state + "Idle=" + top.idle
4977 + " app=" + top.app
4978 + " thr=" + (top.app != null ? top.app.thread : null));
4979 if (top.state == ActivityState.RESUMED
4980 || top.state == ActivityState.PAUSING) {
4981 if (top.idle && top.app != null
4982 && top.app.thread != null) {
4983 topRecord = top;
4984 topThumbnail = top.app.thread;
4985 } else {
4986 top.thumbnailNeeded = true;
4987 }
4988 }
4989 if (pending == null) {
4990 pending = new PendingThumbnailsRecord(receiver);
4991 }
4992 pending.pendingRecords.add(top);
4993 }
4994 list.add(ci);
4995 maxNum--;
4996 top = null;
4997 }
4998 }
4999
5000 if (pending != null) {
5001 mPendingThumbnails.add(pending);
5002 }
5003 }
5004
Joe Onorato8a9b2202010-02-26 18:56:32 -08005005 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005006
5007 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005008 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005009 try {
5010 topThumbnail.requestThumbnail(topRecord);
5011 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005012 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005013 sendPendingThumbnail(null, topRecord, null, null, true);
5014 }
5015 }
5016
5017 if (pending == null && receiver != null) {
5018 // In this case all thumbnails were available and the client
5019 // is being asked to be told when the remaining ones come in...
5020 // which is unusually, since the top-most currently running
5021 // activity should never have a canned thumbnail! Oh well.
5022 try {
5023 receiver.finished();
5024 } catch (RemoteException ex) {
5025 }
5026 }
5027
5028 return list;
5029 }
5030
5031 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5032 int flags) {
5033 synchronized (this) {
5034 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5035 "getRecentTasks()");
5036
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005037 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005039 final int N = mRecentTasks.size();
5040 ArrayList<ActivityManager.RecentTaskInfo> res
5041 = new ArrayList<ActivityManager.RecentTaskInfo>(
5042 maxNum < N ? maxNum : N);
5043 for (int i=0; i<N && maxNum > 0; i++) {
5044 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005045 // Return the entry if desired by the caller. We always return
5046 // the first entry, because callers always expect this to be the
5047 // forground app. We may filter others if the caller has
5048 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5049 // we should exclude the entry.
5050 if (i == 0
5051 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005052 || (tr.intent == null)
5053 || ((tr.intent.getFlags()
5054 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5055 ActivityManager.RecentTaskInfo rti
5056 = new ActivityManager.RecentTaskInfo();
5057 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005058 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005059 rti.baseIntent = new Intent(
5060 tr.intent != null ? tr.intent : tr.affinityIntent);
5061 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005062 rti.description = tr.lastDescription;
5063
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005064 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5065 // Check whether this activity is currently available.
5066 try {
5067 if (rti.origActivity != null) {
5068 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5069 continue;
5070 }
5071 } else if (rti.baseIntent != null) {
5072 if (pm.queryIntentActivities(rti.baseIntent,
5073 null, 0) == null) {
5074 continue;
5075 }
5076 }
5077 } catch (RemoteException e) {
5078 // Will never happen.
5079 }
5080 }
5081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005082 res.add(rti);
5083 maxNum--;
5084 }
5085 }
5086 return res;
5087 }
5088 }
5089
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005090 private TaskRecord taskForIdLocked(int id) {
5091 final int N = mRecentTasks.size();
5092 for (int i=0; i<N; i++) {
5093 TaskRecord tr = mRecentTasks.get(i);
5094 if (tr.taskId == id) {
5095 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005096 }
5097 }
5098 return null;
5099 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005100
5101 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5102 synchronized (this) {
5103 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5104 "getTaskThumbnails()");
5105 TaskRecord tr = taskForIdLocked(id);
5106 if (tr != null) {
5107 return mMainStack.getTaskThumbnailsLocked(tr);
5108 }
5109 }
5110 return null;
5111 }
5112
5113 public boolean removeSubTask(int taskId, int subTaskIndex) {
5114 synchronized (this) {
5115 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5116 "removeSubTask()");
5117 long ident = Binder.clearCallingIdentity();
5118 try {
5119 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5120 } finally {
5121 Binder.restoreCallingIdentity(ident);
5122 }
5123 }
5124 }
5125
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005126 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005127 TaskRecord tr = root.task;
5128 Intent baseIntent = new Intent(
5129 tr.intent != null ? tr.intent : tr.affinityIntent);
5130 ComponentName component = baseIntent.getComponent();
5131 if (component == null) {
5132 Slog.w(TAG, "Now component for base intent of task: " + tr);
5133 return;
5134 }
5135
5136 // Find any running services associated with this app.
5137 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5138 for (ServiceRecord sr : mServices.values()) {
5139 if (sr.packageName.equals(component.getPackageName())) {
5140 services.add(sr);
5141 }
5142 }
5143
5144 // Take care of any running services associated with the app.
5145 for (int i=0; i<services.size(); i++) {
5146 ServiceRecord sr = services.get(i);
5147 if (sr.startRequested) {
5148 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005149 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005150 stopServiceLocked(sr);
5151 } else {
5152 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5153 sr.makeNextStartId(), baseIntent, -1));
5154 if (sr.app != null && sr.app.thread != null) {
5155 sendServiceArgsLocked(sr, false);
5156 }
5157 }
5158 }
5159 }
5160
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005161 if (killProcesses) {
5162 // Find any running processes associated with this app.
5163 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5164 SparseArray<ProcessRecord> appProcs
5165 = mProcessNames.getMap().get(component.getPackageName());
5166 if (appProcs != null) {
5167 for (int i=0; i<appProcs.size(); i++) {
5168 procs.add(appProcs.valueAt(i));
5169 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005170 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005171
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005172 // Kill the running processes.
5173 for (int i=0; i<procs.size(); i++) {
5174 ProcessRecord pr = procs.get(i);
5175 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5176 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5177 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5178 pr.processName, pr.setAdj, "remove task");
5179 Process.killProcessQuiet(pr.pid);
5180 } else {
5181 pr.waitingToKill = "remove task";
5182 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005183 }
5184 }
5185 }
5186
5187 public boolean removeTask(int taskId, int flags) {
5188 synchronized (this) {
5189 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5190 "removeTask()");
5191 long ident = Binder.clearCallingIdentity();
5192 try {
5193 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5194 if (r != null) {
5195 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005196 cleanUpRemovedTaskLocked(r,
5197 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005198 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005199 } else {
5200 TaskRecord tr = null;
5201 int i=0;
5202 while (i < mRecentTasks.size()) {
5203 TaskRecord t = mRecentTasks.get(i);
5204 if (t.taskId == taskId) {
5205 tr = t;
5206 break;
5207 }
5208 i++;
5209 }
5210 if (tr != null) {
5211 if (tr.numActivities <= 0) {
5212 // Caller is just removing a recent task that is
5213 // not actively running. That is easy!
5214 mRecentTasks.remove(i);
5215 } else {
5216 Slog.w(TAG, "removeTask: task " + taskId
5217 + " does not have activities to remove, "
5218 + " but numActivities=" + tr.numActivities
5219 + ": " + tr);
5220 }
5221 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005222 }
5223 } finally {
5224 Binder.restoreCallingIdentity(ident);
5225 }
5226 }
5227 return false;
5228 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005230 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5231 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005232 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005233 TaskRecord jt = startTask;
5234
5235 // First look backwards
5236 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005237 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005238 if (r.task != jt) {
5239 jt = r.task;
5240 if (affinity.equals(jt.affinity)) {
5241 return j;
5242 }
5243 }
5244 }
5245
5246 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005247 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005248 jt = startTask;
5249 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005250 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005251 if (r.task != jt) {
5252 if (affinity.equals(jt.affinity)) {
5253 return j;
5254 }
5255 jt = r.task;
5256 }
5257 }
5258
5259 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005260 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005261 return N-1;
5262 }
5263
5264 return -1;
5265 }
5266
5267 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005268 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005269 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005270 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005271 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5272 "moveTaskToFront()");
5273
5274 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005275 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5276 Binder.getCallingUid(), "Task to front")) {
5277 return;
5278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005279 final long origId = Binder.clearCallingIdentity();
5280 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005281 TaskRecord tr = taskForIdLocked(task);
5282 if (tr != null) {
5283 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5284 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005285 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005286 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5287 // Caller wants the home activity moved with it. To accomplish this,
5288 // we'll just move the home task to the top first.
5289 mMainStack.moveHomeToFrontLocked();
5290 }
5291 mMainStack.moveTaskToFrontLocked(tr, null);
5292 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005293 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005294 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5295 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005296 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005297 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5298 mMainStack.mUserLeaving = true;
5299 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005300 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5301 // Caller wants the home activity moved with it. To accomplish this,
5302 // we'll just move the home task to the top first.
5303 mMainStack.moveHomeToFrontLocked();
5304 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005305 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005306 return;
5307 }
5308 }
5309 } finally {
5310 Binder.restoreCallingIdentity(origId);
5311 }
5312 }
5313 }
5314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005315 public void moveTaskToBack(int task) {
5316 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5317 "moveTaskToBack()");
5318
5319 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005320 if (mMainStack.mResumedActivity != null
5321 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005322 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5323 Binder.getCallingUid(), "Task to back")) {
5324 return;
5325 }
5326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005327 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005328 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005329 Binder.restoreCallingIdentity(origId);
5330 }
5331 }
5332
5333 /**
5334 * Moves an activity, and all of the other activities within the same task, to the bottom
5335 * of the history stack. The activity's order within the task is unchanged.
5336 *
5337 * @param token A reference to the activity we wish to move
5338 * @param nonRoot If false then this only works if the activity is the root
5339 * of a task; if true it will work for any activity in a task.
5340 * @return Returns true if the move completed, false if not.
5341 */
5342 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5343 synchronized(this) {
5344 final long origId = Binder.clearCallingIdentity();
5345 int taskId = getTaskForActivityLocked(token, !nonRoot);
5346 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005347 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005348 }
5349 Binder.restoreCallingIdentity(origId);
5350 }
5351 return false;
5352 }
5353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005354 public void moveTaskBackwards(int task) {
5355 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5356 "moveTaskBackwards()");
5357
5358 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005359 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5360 Binder.getCallingUid(), "Task backwards")) {
5361 return;
5362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005363 final long origId = Binder.clearCallingIdentity();
5364 moveTaskBackwardsLocked(task);
5365 Binder.restoreCallingIdentity(origId);
5366 }
5367 }
5368
5369 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005370 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005371 }
5372
5373 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5374 synchronized(this) {
5375 return getTaskForActivityLocked(token, onlyRoot);
5376 }
5377 }
5378
5379 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005380 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005381 TaskRecord lastTask = null;
5382 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005383 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005384 if (r == token) {
5385 if (!onlyRoot || lastTask != r.task) {
5386 return r.task.taskId;
5387 }
5388 return -1;
5389 }
5390 lastTask = r.task;
5391 }
5392
5393 return -1;
5394 }
5395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005396 public void finishOtherInstances(IBinder token, ComponentName className) {
5397 synchronized(this) {
5398 final long origId = Binder.clearCallingIdentity();
5399
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005400 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005401 TaskRecord lastTask = null;
5402 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005403 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005404 if (r.realActivity.equals(className)
5405 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005406 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005407 null, "others")) {
5408 i--;
5409 N--;
5410 }
5411 }
5412 lastTask = r.task;
5413 }
5414
5415 Binder.restoreCallingIdentity(origId);
5416 }
5417 }
5418
5419 // =========================================================
5420 // THUMBNAILS
5421 // =========================================================
5422
5423 public void reportThumbnail(IBinder token,
5424 Bitmap thumbnail, CharSequence description) {
5425 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5426 final long origId = Binder.clearCallingIdentity();
5427 sendPendingThumbnail(null, token, thumbnail, description, true);
5428 Binder.restoreCallingIdentity(origId);
5429 }
5430
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005431 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 Bitmap thumbnail, CharSequence description, boolean always) {
5433 TaskRecord task = null;
5434 ArrayList receivers = null;
5435
5436 //System.out.println("Send pending thumbnail: " + r);
5437
5438 synchronized(this) {
5439 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005440 r = mMainStack.isInStackLocked(token);
5441 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005442 return;
5443 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005444 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005445 if (thumbnail == null && r.thumbHolder != null) {
5446 thumbnail = r.thumbHolder.lastThumbnail;
5447 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005448 }
5449 if (thumbnail == null && !always) {
5450 // If there is no thumbnail, and this entry is not actually
5451 // going away, then abort for now and pick up the next
5452 // thumbnail we get.
5453 return;
5454 }
5455 task = r.task;
5456
5457 int N = mPendingThumbnails.size();
5458 int i=0;
5459 while (i<N) {
5460 PendingThumbnailsRecord pr =
5461 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5462 //System.out.println("Looking in " + pr.pendingRecords);
5463 if (pr.pendingRecords.remove(r)) {
5464 if (receivers == null) {
5465 receivers = new ArrayList();
5466 }
5467 receivers.add(pr);
5468 if (pr.pendingRecords.size() == 0) {
5469 pr.finished = true;
5470 mPendingThumbnails.remove(i);
5471 N--;
5472 continue;
5473 }
5474 }
5475 i++;
5476 }
5477 }
5478
5479 if (receivers != null) {
5480 final int N = receivers.size();
5481 for (int i=0; i<N; i++) {
5482 try {
5483 PendingThumbnailsRecord pr =
5484 (PendingThumbnailsRecord)receivers.get(i);
5485 pr.receiver.newThumbnail(
5486 task != null ? task.taskId : -1, thumbnail, description);
5487 if (pr.finished) {
5488 pr.receiver.finished();
5489 }
5490 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005491 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005492 }
5493 }
5494 }
5495 }
5496
5497 // =========================================================
5498 // CONTENT PROVIDERS
5499 // =========================================================
5500
Jeff Brown10e89712011-07-08 18:52:57 -07005501 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5502 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005503 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005504 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005505 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005506 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005507 } catch (RemoteException ex) {
5508 }
5509 if (providers != null) {
5510 final int N = providers.size();
5511 for (int i=0; i<N; i++) {
5512 ProviderInfo cpi =
5513 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005514 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5515 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005516 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005517 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005518 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005519 }
5520 app.pubProviders.put(cpi.name, cpr);
5521 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005522 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005523 }
5524 }
5525 return providers;
5526 }
5527
5528 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005529 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005530 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5531 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5532 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005533 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005534 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005535 return null;
5536 }
5537 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005538 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005539 == PackageManager.PERMISSION_GRANTED) {
5540 return null;
5541 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005542
5543 PathPermission[] pps = cpi.pathPermissions;
5544 if (pps != null) {
5545 int i = pps.length;
5546 while (i > 0) {
5547 i--;
5548 PathPermission pp = pps[i];
5549 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005550 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005551 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005552 return null;
5553 }
5554 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005555 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005556 == PackageManager.PERMISSION_GRANTED) {
5557 return null;
5558 }
5559 }
5560 }
5561
Dianne Hackbornb424b632010-08-18 15:59:05 -07005562 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5563 if (perms != null) {
5564 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5565 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5566 return null;
5567 }
5568 }
5569 }
5570
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005571 String msg;
5572 if (!cpi.exported) {
5573 msg = "Permission Denial: opening provider " + cpi.name
5574 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5575 + ", uid=" + callingUid + ") that is not exported from uid "
5576 + cpi.applicationInfo.uid;
5577 } else {
5578 msg = "Permission Denial: opening provider " + cpi.name
5579 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5580 + ", uid=" + callingUid + ") requires "
5581 + cpi.readPermission + " or " + cpi.writePermission;
5582 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005583 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005584 return msg;
5585 }
5586
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005587 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5588 if (r != null) {
5589 Integer cnt = r.conProviders.get(cpr);
5590 if (DEBUG_PROVIDER) Slog.v(TAG,
5591 "Adding provider requested by "
5592 + r.processName + " from process "
5593 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5594 + " cnt=" + (cnt == null ? 1 : cnt));
5595 if (cnt == null) {
5596 cpr.clients.add(r);
5597 r.conProviders.put(cpr, new Integer(1));
5598 return true;
5599 } else {
5600 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5601 }
5602 } else {
5603 cpr.externals++;
5604 }
5605 return false;
5606 }
5607
5608 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5609 if (r != null) {
5610 Integer cnt = r.conProviders.get(cpr);
5611 if (DEBUG_PROVIDER) Slog.v(TAG,
5612 "Removing provider requested by "
5613 + r.processName + " from process "
5614 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5615 + " cnt=" + cnt);
5616 if (cnt == null || cnt.intValue() <= 1) {
5617 cpr.clients.remove(r);
5618 r.conProviders.remove(cpr);
5619 return true;
5620 } else {
5621 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5622 }
5623 } else {
5624 cpr.externals++;
5625 }
5626 return false;
5627 }
5628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005629 private final ContentProviderHolder getContentProviderImpl(
5630 IApplicationThread caller, String name) {
5631 ContentProviderRecord cpr;
5632 ProviderInfo cpi = null;
5633
5634 synchronized(this) {
5635 ProcessRecord r = null;
5636 if (caller != null) {
5637 r = getRecordForAppLocked(caller);
5638 if (r == null) {
5639 throw new SecurityException(
5640 "Unable to find app for caller " + caller
5641 + " (pid=" + Binder.getCallingPid()
5642 + ") when getting content provider " + name);
5643 }
5644 }
5645
5646 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005647 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005648 boolean providerRunning = cpr != null;
5649 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005650 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005651 String msg;
5652 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5653 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005654 }
5655
5656 if (r != null && cpr.canRunHere(r)) {
5657 // This provider has been published or is in the process
5658 // of being published... but it is also allowed to run
5659 // in the caller's process, so don't make a connection
5660 // and just let the caller instantiate its own instance.
5661 if (cpr.provider != null) {
5662 // don't give caller the provider object, it needs
5663 // to make its own.
5664 cpr = new ContentProviderRecord(cpr);
5665 }
5666 return cpr;
5667 }
5668
5669 final long origId = Binder.clearCallingIdentity();
5670
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005671 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005672 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005673 final boolean countChanged = incProviderCount(r, cpr);
5674 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005675 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005676 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005677 // make sure to count it as being accessed and thus
5678 // back up on the LRU list. This is good because
5679 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005680 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005681 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005682 }
5683
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005684 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005685 if (false) {
5686 if (cpr.name.flattenToShortString().equals(
5687 "com.android.providers.calendar/.CalendarProvider2")) {
5688 Slog.v(TAG, "****************** KILLING "
5689 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005690 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005691 }
5692 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005693 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005694 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5695 // NOTE: there is still a race here where a signal could be
5696 // pending on the process even though we managed to update its
5697 // adj level. Not sure what to do about this, but at least
5698 // the race is now smaller.
5699 if (!success) {
5700 // Uh oh... it looks like the provider's process
5701 // has been killed on us. We need to wait for a new
5702 // process to be started, and make sure its death
5703 // doesn't kill our process.
5704 Slog.i(TAG,
5705 "Existing provider " + cpr.name.flattenToShortString()
5706 + " is crashing; detaching " + r);
5707 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005708 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005709 if (!lastRef) {
5710 // This wasn't the last ref our process had on
5711 // the provider... we have now been killed, bail.
5712 return null;
5713 }
5714 providerRunning = false;
5715 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005716 }
5717
5718 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005719 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005720
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005721 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005722 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005723 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005724 resolveContentProvider(name,
5725 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005726 } catch (RemoteException ex) {
5727 }
5728 if (cpi == null) {
5729 return null;
5730 }
5731
Dianne Hackbornb424b632010-08-18 15:59:05 -07005732 String msg;
5733 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5734 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005735 }
5736
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005737 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005738 && !cpi.processName.equals("system")) {
5739 // If this content provider does not run in the system
5740 // process, and the system is not yet ready to run other
5741 // processes, then fail fast instead of hanging.
5742 throw new IllegalArgumentException(
5743 "Attempt to launch content provider before system ready");
5744 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005745
5746 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5747 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005748 final boolean firstClass = cpr == null;
5749 if (firstClass) {
5750 try {
5751 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005752 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005753 getApplicationInfo(
5754 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005755 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005756 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005757 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005758 + cpi.name);
5759 return null;
5760 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005761 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005762 } catch (RemoteException ex) {
5763 // pm is in same process, this will never happen.
5764 }
5765 }
5766
5767 if (r != null && cpr.canRunHere(r)) {
5768 // If this is a multiprocess provider, then just return its
5769 // info and allow the caller to instantiate it. Only do
5770 // this if the provider is the same user as the caller's
5771 // process, or can run as root (so can be in any process).
5772 return cpr;
5773 }
5774
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005775 if (DEBUG_PROVIDER) {
5776 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005777 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005778 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005779 }
5780
5781 // This is single process, and our app is now connecting to it.
5782 // See if we are already in the process of launching this
5783 // provider.
5784 final int N = mLaunchingProviders.size();
5785 int i;
5786 for (i=0; i<N; i++) {
5787 if (mLaunchingProviders.get(i) == cpr) {
5788 break;
5789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790 }
5791
5792 // If the provider is not already being launched, then get it
5793 // started.
5794 if (i >= N) {
5795 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005796
5797 try {
5798 // Content provider is now in use, its package can't be stopped.
5799 try {
5800 AppGlobals.getPackageManager().setPackageStoppedState(
5801 cpr.appInfo.packageName, false);
5802 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005803 } catch (IllegalArgumentException e) {
5804 Slog.w(TAG, "Failed trying to unstop package "
5805 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005806 }
5807
5808 ProcessRecord proc = startProcessLocked(cpi.processName,
5809 cpr.appInfo, false, 0, "content provider",
5810 new ComponentName(cpi.applicationInfo.packageName,
5811 cpi.name), false);
5812 if (proc == null) {
5813 Slog.w(TAG, "Unable to launch app "
5814 + cpi.applicationInfo.packageName + "/"
5815 + cpi.applicationInfo.uid + " for provider "
5816 + name + ": process is bad");
5817 return null;
5818 }
5819 cpr.launchingApp = proc;
5820 mLaunchingProviders.add(cpr);
5821 } finally {
5822 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005823 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005824 }
5825
5826 // Make sure the provider is published (the same provider class
5827 // may be published under multiple names).
5828 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005829 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005830 }
5831 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005832 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005833 }
5834 }
5835
5836 // Wait for the provider to be published...
5837 synchronized (cpr) {
5838 while (cpr.provider == null) {
5839 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005840 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005841 + cpi.applicationInfo.packageName + "/"
5842 + cpi.applicationInfo.uid + " for provider "
5843 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005844 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005845 cpi.applicationInfo.packageName,
5846 cpi.applicationInfo.uid, name);
5847 return null;
5848 }
5849 try {
5850 cpr.wait();
5851 } catch (InterruptedException ex) {
5852 }
5853 }
5854 }
5855 return cpr;
5856 }
5857
5858 public final ContentProviderHolder getContentProvider(
5859 IApplicationThread caller, String name) {
5860 if (caller == null) {
5861 String msg = "null IApplicationThread when getting content provider "
5862 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005863 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005864 throw new SecurityException(msg);
5865 }
5866
5867 return getContentProviderImpl(caller, name);
5868 }
5869
5870 private ContentProviderHolder getContentProviderExternal(String name) {
5871 return getContentProviderImpl(null, name);
5872 }
5873
5874 /**
5875 * Drop a content provider from a ProcessRecord's bookkeeping
5876 * @param cpr
5877 */
5878 public void removeContentProvider(IApplicationThread caller, String name) {
5879 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005880 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005881 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005882 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005883 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005884 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005885 return;
5886 }
5887 final ProcessRecord r = getRecordForAppLocked(caller);
5888 if (r == null) {
5889 throw new SecurityException(
5890 "Unable to find app for caller " + caller +
5891 " when removing content provider " + name);
5892 }
5893 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005894 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5895 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005896 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005897 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005898 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005899 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005900 return;
5901 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005902 if (decProviderCount(r, localCpr)) {
5903 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005906 }
5907 }
5908
5909 private void removeContentProviderExternal(String name) {
5910 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005911 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005912 if(cpr == null) {
5913 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005914 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005915 return;
5916 }
5917
5918 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005919 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5920 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005921 localCpr.externals--;
5922 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005923 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005924 }
5925 updateOomAdjLocked();
5926 }
5927 }
5928
5929 public final void publishContentProviders(IApplicationThread caller,
5930 List<ContentProviderHolder> providers) {
5931 if (providers == null) {
5932 return;
5933 }
5934
5935 synchronized(this) {
5936 final ProcessRecord r = getRecordForAppLocked(caller);
5937 if (r == null) {
5938 throw new SecurityException(
5939 "Unable to find app for caller " + caller
5940 + " (pid=" + Binder.getCallingPid()
5941 + ") when publishing content providers");
5942 }
5943
5944 final long origId = Binder.clearCallingIdentity();
5945
5946 final int N = providers.size();
5947 for (int i=0; i<N; i++) {
5948 ContentProviderHolder src = providers.get(i);
5949 if (src == null || src.info == null || src.provider == null) {
5950 continue;
5951 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005952 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005953 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005954 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
5955 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005956 String names[] = dst.info.authority.split(";");
5957 for (int j = 0; j < names.length; j++) {
5958 mProvidersByName.put(names[j], dst);
5959 }
5960
5961 int NL = mLaunchingProviders.size();
5962 int j;
5963 for (j=0; j<NL; j++) {
5964 if (mLaunchingProviders.get(j) == dst) {
5965 mLaunchingProviders.remove(j);
5966 j--;
5967 NL--;
5968 }
5969 }
5970 synchronized (dst) {
5971 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005972 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005973 dst.notifyAll();
5974 }
5975 updateOomAdjLocked(r);
5976 }
5977 }
5978
5979 Binder.restoreCallingIdentity(origId);
5980 }
5981 }
5982
5983 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07005984 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005985 synchronized (mSelf) {
5986 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5987 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005988 if (providers != null) {
5989 for (int i=providers.size()-1; i>=0; i--) {
5990 ProviderInfo pi = (ProviderInfo)providers.get(i);
5991 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5992 Slog.w(TAG, "Not installing system proc provider " + pi.name
5993 + ": not system .apk");
5994 providers.remove(i);
5995 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005996 }
5997 }
5998 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005999 if (providers != null) {
6000 mSystemThread.installSystemProviders(providers);
6001 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006002
6003 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006004
6005 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006006 }
6007
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006008 /**
6009 * Allows app to retrieve the MIME type of a URI without having permission
6010 * to access its content provider.
6011 *
6012 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6013 *
6014 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6015 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6016 */
6017 public String getProviderMimeType(Uri uri) {
6018 final String name = uri.getAuthority();
6019 final long ident = Binder.clearCallingIdentity();
6020 ContentProviderHolder holder = null;
6021
6022 try {
6023 holder = getContentProviderExternal(name);
6024 if (holder != null) {
6025 return holder.provider.getType(uri);
6026 }
6027 } catch (RemoteException e) {
6028 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6029 return null;
6030 } finally {
6031 if (holder != null) {
6032 removeContentProviderExternal(name);
6033 }
6034 Binder.restoreCallingIdentity(ident);
6035 }
6036
6037 return null;
6038 }
6039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006040 // =========================================================
6041 // GLOBAL MANAGEMENT
6042 // =========================================================
6043
6044 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6045 ApplicationInfo info, String customProcess) {
6046 String proc = customProcess != null ? customProcess : info.processName;
6047 BatteryStatsImpl.Uid.Proc ps = null;
6048 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6049 synchronized (stats) {
6050 ps = stats.getProcessStatsLocked(info.uid, proc);
6051 }
6052 return new ProcessRecord(ps, thread, info, proc);
6053 }
6054
6055 final ProcessRecord addAppLocked(ApplicationInfo info) {
6056 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6057
6058 if (app == null) {
6059 app = newProcessRecordLocked(null, info, null);
6060 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006061 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006062 }
6063
Dianne Hackborne7f97212011-02-24 14:40:20 -08006064 // This package really, really can not be stopped.
6065 try {
6066 AppGlobals.getPackageManager().setPackageStoppedState(
6067 info.packageName, false);
6068 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006069 } catch (IllegalArgumentException e) {
6070 Slog.w(TAG, "Failed trying to unstop package "
6071 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006072 }
6073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006074 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6075 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6076 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07006077 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006078 }
6079 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6080 mPersistentStartingProcesses.add(app);
6081 startProcessLocked(app, "added application", app.processName);
6082 }
6083
6084 return app;
6085 }
6086
6087 public void unhandledBack() {
6088 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6089 "unhandledBack()");
6090
6091 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006092 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006093 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006094 TAG, "Performing unhandledBack(): stack size = " + count);
6095 if (count > 1) {
6096 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006097 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6099 Binder.restoreCallingIdentity(origId);
6100 }
6101 }
6102 }
6103
6104 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6105 String name = uri.getAuthority();
6106 ContentProviderHolder cph = getContentProviderExternal(name);
6107 ParcelFileDescriptor pfd = null;
6108 if (cph != null) {
6109 // We record the binder invoker's uid in thread-local storage before
6110 // going to the content provider to open the file. Later, in the code
6111 // that handles all permissions checks, we look for this uid and use
6112 // that rather than the Activity Manager's own uid. The effect is that
6113 // we do the check against the caller's permissions even though it looks
6114 // to the content provider like the Activity Manager itself is making
6115 // the request.
6116 sCallerIdentity.set(new Identity(
6117 Binder.getCallingPid(), Binder.getCallingUid()));
6118 try {
6119 pfd = cph.provider.openFile(uri, "r");
6120 } catch (FileNotFoundException e) {
6121 // do nothing; pfd will be returned null
6122 } finally {
6123 // Ensure that whatever happens, we clean up the identity state
6124 sCallerIdentity.remove();
6125 }
6126
6127 // We've got the fd now, so we're done with the provider.
6128 removeContentProviderExternal(name);
6129 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006130 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006131 }
6132 return pfd;
6133 }
6134
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006135 // Actually is sleeping or shutting down or whatever else in the future
6136 // is an inactive state.
6137 public boolean isSleeping() {
6138 return mSleeping || mShuttingDown;
6139 }
6140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006141 public void goingToSleep() {
6142 synchronized(this) {
6143 mSleeping = true;
6144 mWindowManager.setEventDispatching(false);
6145
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006146 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006147
6148 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006149 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006150 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6151 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006152 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006153 }
6154 }
6155
Dianne Hackborn55280a92009-05-07 15:53:46 -07006156 public boolean shutdown(int timeout) {
6157 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6158 != PackageManager.PERMISSION_GRANTED) {
6159 throw new SecurityException("Requires permission "
6160 + android.Manifest.permission.SHUTDOWN);
6161 }
6162
6163 boolean timedout = false;
6164
6165 synchronized(this) {
6166 mShuttingDown = true;
6167 mWindowManager.setEventDispatching(false);
6168
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006169 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006170 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006171 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006172 while (mMainStack.mResumedActivity != null
6173 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006174 long delay = endTime - System.currentTimeMillis();
6175 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006176 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006177 timedout = true;
6178 break;
6179 }
6180 try {
6181 this.wait();
6182 } catch (InterruptedException e) {
6183 }
6184 }
6185 }
6186 }
6187
6188 mUsageStatsService.shutdown();
6189 mBatteryStatsService.shutdown();
6190
6191 return timedout;
6192 }
6193
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006194 public final void activitySlept(IBinder token) {
6195 if (localLOGV) Slog.v(
6196 TAG, "Activity slept: token=" + token);
6197
6198 ActivityRecord r = null;
6199
6200 final long origId = Binder.clearCallingIdentity();
6201
6202 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006203 r = mMainStack.isInStackLocked(token);
6204 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006205 mMainStack.activitySleptLocked(r);
6206 }
6207 }
6208
6209 Binder.restoreCallingIdentity(origId);
6210 }
6211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006212 public void wakingUp() {
6213 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006214 mWindowManager.setEventDispatching(true);
6215 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006216 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006217 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006218 }
6219 }
6220
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006221 public void stopAppSwitches() {
6222 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6223 != PackageManager.PERMISSION_GRANTED) {
6224 throw new SecurityException("Requires permission "
6225 + android.Manifest.permission.STOP_APP_SWITCHES);
6226 }
6227
6228 synchronized(this) {
6229 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6230 + APP_SWITCH_DELAY_TIME;
6231 mDidAppSwitch = false;
6232 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6233 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6234 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6235 }
6236 }
6237
6238 public void resumeAppSwitches() {
6239 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6240 != PackageManager.PERMISSION_GRANTED) {
6241 throw new SecurityException("Requires permission "
6242 + android.Manifest.permission.STOP_APP_SWITCHES);
6243 }
6244
6245 synchronized(this) {
6246 // Note that we don't execute any pending app switches... we will
6247 // let those wait until either the timeout, or the next start
6248 // activity request.
6249 mAppSwitchesAllowedTime = 0;
6250 }
6251 }
6252
6253 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6254 String name) {
6255 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6256 return true;
6257 }
6258
6259 final int perm = checkComponentPermission(
6260 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006261 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006262 if (perm == PackageManager.PERMISSION_GRANTED) {
6263 return true;
6264 }
6265
Joe Onorato8a9b2202010-02-26 18:56:32 -08006266 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006267 return false;
6268 }
6269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006270 public void setDebugApp(String packageName, boolean waitForDebugger,
6271 boolean persistent) {
6272 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6273 "setDebugApp()");
6274
6275 // Note that this is not really thread safe if there are multiple
6276 // callers into it at the same time, but that's not a situation we
6277 // care about.
6278 if (persistent) {
6279 final ContentResolver resolver = mContext.getContentResolver();
6280 Settings.System.putString(
6281 resolver, Settings.System.DEBUG_APP,
6282 packageName);
6283 Settings.System.putInt(
6284 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6285 waitForDebugger ? 1 : 0);
6286 }
6287
6288 synchronized (this) {
6289 if (!persistent) {
6290 mOrigDebugApp = mDebugApp;
6291 mOrigWaitForDebugger = mWaitForDebugger;
6292 }
6293 mDebugApp = packageName;
6294 mWaitForDebugger = waitForDebugger;
6295 mDebugTransient = !persistent;
6296 if (packageName != null) {
6297 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006298 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006299 Binder.restoreCallingIdentity(origId);
6300 }
6301 }
6302 }
6303
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006304 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6305 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6306 synchronized (this) {
6307 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6308 if (!isDebuggable) {
6309 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6310 throw new SecurityException("Process not debuggable: " + app.packageName);
6311 }
6312 }
6313 mProfileApp = processName;
6314 mProfileFile = profileFile;
6315 if (mProfileFd != null) {
6316 try {
6317 mProfileFd.close();
6318 } catch (IOException e) {
6319 }
6320 mProfileFd = null;
6321 }
6322 mProfileFd = profileFd;
6323 mProfileType = 0;
6324 mAutoStopProfiler = autoStopProfiler;
6325 }
6326 }
6327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006328 public void setAlwaysFinish(boolean enabled) {
6329 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6330 "setAlwaysFinish()");
6331
6332 Settings.System.putInt(
6333 mContext.getContentResolver(),
6334 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6335
6336 synchronized (this) {
6337 mAlwaysFinishActivities = enabled;
6338 }
6339 }
6340
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006341 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006342 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006343 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006344 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006345 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006346 }
6347 }
6348
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006349 public boolean isUserAMonkey() {
6350 // For now the fact that there is a controller implies
6351 // we have a monkey.
6352 synchronized (this) {
6353 return mController != null;
6354 }
6355 }
6356
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006357 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006358 synchronized (this) {
6359 mWatchers.register(watcher);
6360 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006361 }
6362
6363 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006364 synchronized (this) {
6365 mWatchers.unregister(watcher);
6366 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006367 }
6368
Jeff Sharkeya4620792011-05-20 15:29:23 -07006369 public void registerProcessObserver(IProcessObserver observer) {
6370 mProcessObservers.register(observer);
6371 }
6372
6373 public void unregisterProcessObserver(IProcessObserver observer) {
6374 mProcessObservers.unregister(observer);
6375 }
6376
Daniel Sandler69a48172010-06-23 16:29:36 -04006377 public void setImmersive(IBinder token, boolean immersive) {
6378 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006379 ActivityRecord r = mMainStack.isInStackLocked(token);
6380 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006381 throw new IllegalArgumentException();
6382 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006383 r.immersive = immersive;
6384 }
6385 }
6386
6387 public boolean isImmersive(IBinder token) {
6388 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006389 ActivityRecord r = mMainStack.isInStackLocked(token);
6390 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006391 throw new IllegalArgumentException();
6392 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006393 return r.immersive;
6394 }
6395 }
6396
6397 public boolean isTopActivityImmersive() {
6398 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006399 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006400 return (r != null) ? r.immersive : false;
6401 }
6402 }
6403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006404 public final void enterSafeMode() {
6405 synchronized(this) {
6406 // It only makes sense to do this before the system is ready
6407 // and started launching other packages.
6408 if (!mSystemReady) {
6409 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006410 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006411 } catch (RemoteException e) {
6412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006413 }
6414 }
6415 }
6416
Jeff Brownb09abc12011-01-13 21:08:27 -08006417 public final void showSafeModeOverlay() {
6418 View v = LayoutInflater.from(mContext).inflate(
6419 com.android.internal.R.layout.safe_mode, null);
6420 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6421 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6422 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6423 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6424 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6425 lp.format = v.getBackground().getOpacity();
6426 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6427 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6428 ((WindowManager)mContext.getSystemService(
6429 Context.WINDOW_SERVICE)).addView(v, lp);
6430 }
6431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006432 public void noteWakeupAlarm(IIntentSender sender) {
6433 if (!(sender instanceof PendingIntentRecord)) {
6434 return;
6435 }
6436 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6437 synchronized (stats) {
6438 if (mBatteryStatsService.isOnBattery()) {
6439 mBatteryStatsService.enforceCallingPermission();
6440 PendingIntentRecord rec = (PendingIntentRecord)sender;
6441 int MY_UID = Binder.getCallingUid();
6442 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6443 BatteryStatsImpl.Uid.Pkg pkg =
6444 stats.getPackageStatsLocked(uid, rec.key.packageName);
6445 pkg.incWakeupsLocked();
6446 }
6447 }
6448 }
6449
Dianne Hackborn64825172011-03-02 21:32:58 -08006450 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006451 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006452 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006453 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006454 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006455 // XXX Note: don't acquire main activity lock here, because the window
6456 // manager calls in with its locks held.
6457
6458 boolean killed = false;
6459 synchronized (mPidsSelfLocked) {
6460 int[] types = new int[pids.length];
6461 int worstType = 0;
6462 for (int i=0; i<pids.length; i++) {
6463 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6464 if (proc != null) {
6465 int type = proc.setAdj;
6466 types[i] = type;
6467 if (type > worstType) {
6468 worstType = type;
6469 }
6470 }
6471 }
6472
Dianne Hackborn64825172011-03-02 21:32:58 -08006473 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006474 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006475 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6476 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006477 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006478
6479 // If this is not a secure call, don't let it kill processes that
6480 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006481 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6482 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006483 }
6484
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006485 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006486 for (int i=0; i<pids.length; i++) {
6487 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6488 if (proc == null) {
6489 continue;
6490 }
6491 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006492 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006493 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006494 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6495 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006496 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006497 proc.killedBackground = true;
6498 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006499 }
6500 }
6501 }
6502 return killed;
6503 }
6504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006505 public final void startRunning(String pkg, String cls, String action,
6506 String data) {
6507 synchronized(this) {
6508 if (mStartRunning) {
6509 return;
6510 }
6511 mStartRunning = true;
6512 mTopComponent = pkg != null && cls != null
6513 ? new ComponentName(pkg, cls) : null;
6514 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6515 mTopData = data;
6516 if (!mSystemReady) {
6517 return;
6518 }
6519 }
6520
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006521 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006522 }
6523
6524 private void retrieveSettings() {
6525 final ContentResolver resolver = mContext.getContentResolver();
6526 String debugApp = Settings.System.getString(
6527 resolver, Settings.System.DEBUG_APP);
6528 boolean waitForDebugger = Settings.System.getInt(
6529 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6530 boolean alwaysFinishActivities = Settings.System.getInt(
6531 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6532
6533 Configuration configuration = new Configuration();
6534 Settings.System.getConfiguration(resolver, configuration);
6535
6536 synchronized (this) {
6537 mDebugApp = mOrigDebugApp = debugApp;
6538 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6539 mAlwaysFinishActivities = alwaysFinishActivities;
6540 // This happens before any activities are started, so we can
6541 // change mConfiguration in-place.
6542 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006543 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006544 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006545 }
6546 }
6547
6548 public boolean testIsSystemReady() {
6549 // no need to synchronize(this) just to read & return the value
6550 return mSystemReady;
6551 }
6552
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006553 private static File getCalledPreBootReceiversFile() {
6554 File dataDir = Environment.getDataDirectory();
6555 File systemDir = new File(dataDir, "system");
6556 File fname = new File(systemDir, "called_pre_boots.dat");
6557 return fname;
6558 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006559
6560 static final int LAST_DONE_VERSION = 10000;
6561
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006562 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6563 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6564 File file = getCalledPreBootReceiversFile();
6565 FileInputStream fis = null;
6566 try {
6567 fis = new FileInputStream(file);
6568 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006569 int fvers = dis.readInt();
6570 if (fvers == LAST_DONE_VERSION) {
6571 String vers = dis.readUTF();
6572 String codename = dis.readUTF();
6573 String build = dis.readUTF();
6574 if (android.os.Build.VERSION.RELEASE.equals(vers)
6575 && android.os.Build.VERSION.CODENAME.equals(codename)
6576 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6577 int num = dis.readInt();
6578 while (num > 0) {
6579 num--;
6580 String pkg = dis.readUTF();
6581 String cls = dis.readUTF();
6582 lastDoneReceivers.add(new ComponentName(pkg, cls));
6583 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006584 }
6585 }
6586 } catch (FileNotFoundException e) {
6587 } catch (IOException e) {
6588 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6589 } finally {
6590 if (fis != null) {
6591 try {
6592 fis.close();
6593 } catch (IOException e) {
6594 }
6595 }
6596 }
6597 return lastDoneReceivers;
6598 }
6599
6600 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6601 File file = getCalledPreBootReceiversFile();
6602 FileOutputStream fos = null;
6603 DataOutputStream dos = null;
6604 try {
6605 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6606 fos = new FileOutputStream(file);
6607 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006608 dos.writeInt(LAST_DONE_VERSION);
6609 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006610 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006611 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006612 dos.writeInt(list.size());
6613 for (int i=0; i<list.size(); i++) {
6614 dos.writeUTF(list.get(i).getPackageName());
6615 dos.writeUTF(list.get(i).getClassName());
6616 }
6617 } catch (IOException e) {
6618 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6619 file.delete();
6620 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006621 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006622 if (dos != null) {
6623 try {
6624 dos.close();
6625 } catch (IOException e) {
6626 // TODO Auto-generated catch block
6627 e.printStackTrace();
6628 }
6629 }
6630 }
6631 }
6632
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006633 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006634 synchronized(this) {
6635 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006636 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006637 return;
6638 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006639
6640 // Check to see if there are any update receivers to run.
6641 if (!mDidUpdate) {
6642 if (mWaitingUpdate) {
6643 return;
6644 }
6645 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6646 List<ResolveInfo> ris = null;
6647 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006648 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006649 intent, null, 0);
6650 } catch (RemoteException e) {
6651 }
6652 if (ris != null) {
6653 for (int i=ris.size()-1; i>=0; i--) {
6654 if ((ris.get(i).activityInfo.applicationInfo.flags
6655 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6656 ris.remove(i);
6657 }
6658 }
6659 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006660
6661 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6662
6663 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006664 for (int i=0; i<ris.size(); i++) {
6665 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006666 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6667 if (lastDoneReceivers.contains(comp)) {
6668 ris.remove(i);
6669 i--;
6670 }
6671 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006672
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006673 for (int i=0; i<ris.size(); i++) {
6674 ActivityInfo ai = ris.get(i).activityInfo;
6675 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6676 doneReceivers.add(comp);
6677 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006678 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006679 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006680 finisher = new IIntentReceiver.Stub() {
6681 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006682 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006683 boolean sticky) {
6684 // The raw IIntentReceiver interface is called
6685 // with the AM lock held, so redispatch to
6686 // execute our code without the lock.
6687 mHandler.post(new Runnable() {
6688 public void run() {
6689 synchronized (ActivityManagerService.this) {
6690 mDidUpdate = true;
6691 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006692 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006693 showBootMessage(mContext.getText(
6694 R.string.android_upgrading_complete),
6695 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006696 systemReady(goingCallback);
6697 }
6698 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006699 }
6700 };
6701 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006702 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006703 broadcastIntentLocked(null, null, intent, null, finisher,
6704 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006705 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006706 mWaitingUpdate = true;
6707 }
6708 }
6709 }
6710 if (mWaitingUpdate) {
6711 return;
6712 }
6713 mDidUpdate = true;
6714 }
6715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006716 mSystemReady = true;
6717 if (!mStartRunning) {
6718 return;
6719 }
6720 }
6721
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006722 ArrayList<ProcessRecord> procsToKill = null;
6723 synchronized(mPidsSelfLocked) {
6724 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6725 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6726 if (!isAllowedWhileBooting(proc.info)){
6727 if (procsToKill == null) {
6728 procsToKill = new ArrayList<ProcessRecord>();
6729 }
6730 procsToKill.add(proc);
6731 }
6732 }
6733 }
6734
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006735 synchronized(this) {
6736 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006737 for (int i=procsToKill.size()-1; i>=0; i--) {
6738 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006739 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006740 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006741 }
6742 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006743
6744 // Now that we have cleaned up any update processes, we
6745 // are ready to start launching real processes and know that
6746 // we won't trample on them any more.
6747 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006748 }
6749
Joe Onorato8a9b2202010-02-26 18:56:32 -08006750 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006751 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006752 SystemClock.uptimeMillis());
6753
6754 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006755 // Make sure we have no pre-ready processes sitting around.
6756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006757 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6758 ResolveInfo ri = mContext.getPackageManager()
6759 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006760 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006761 CharSequence errorMsg = null;
6762 if (ri != null) {
6763 ActivityInfo ai = ri.activityInfo;
6764 ApplicationInfo app = ai.applicationInfo;
6765 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6766 mTopAction = Intent.ACTION_FACTORY_TEST;
6767 mTopData = null;
6768 mTopComponent = new ComponentName(app.packageName,
6769 ai.name);
6770 } else {
6771 errorMsg = mContext.getResources().getText(
6772 com.android.internal.R.string.factorytest_not_system);
6773 }
6774 } else {
6775 errorMsg = mContext.getResources().getText(
6776 com.android.internal.R.string.factorytest_no_action);
6777 }
6778 if (errorMsg != null) {
6779 mTopAction = null;
6780 mTopData = null;
6781 mTopComponent = null;
6782 Message msg = Message.obtain();
6783 msg.what = SHOW_FACTORY_ERROR_MSG;
6784 msg.getData().putCharSequence("msg", errorMsg);
6785 mHandler.sendMessage(msg);
6786 }
6787 }
6788 }
6789
6790 retrieveSettings();
6791
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006792 if (goingCallback != null) goingCallback.run();
6793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006794 synchronized (this) {
6795 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6796 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006797 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006798 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006799 if (apps != null) {
6800 int N = apps.size();
6801 int i;
6802 for (i=0; i<N; i++) {
6803 ApplicationInfo info
6804 = (ApplicationInfo)apps.get(i);
6805 if (info != null &&
6806 !info.packageName.equals("android")) {
6807 addAppLocked(info);
6808 }
6809 }
6810 }
6811 } catch (RemoteException ex) {
6812 // pm is in same process, this will never happen.
6813 }
6814 }
6815
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006816 // Start up initial activity.
6817 mBooting = true;
6818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006819 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006820 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006821 Message msg = Message.obtain();
6822 msg.what = SHOW_UID_ERROR_MSG;
6823 mHandler.sendMessage(msg);
6824 }
6825 } catch (RemoteException e) {
6826 }
6827
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006828 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006829 }
6830 }
6831
Dan Egnorb7f03672009-12-09 16:22:32 -08006832 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006833 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006834 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006835 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006836 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006837 startAppProblemLocked(app);
6838 app.stopFreezingAllLocked();
6839 return handleAppCrashLocked(app);
6840 }
6841
Dan Egnorb7f03672009-12-09 16:22:32 -08006842 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006843 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006844 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006845 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006846 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6847 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006848 startAppProblemLocked(app);
6849 app.stopFreezingAllLocked();
6850 }
6851
6852 /**
6853 * Generate a process error record, suitable for attachment to a ProcessRecord.
6854 *
6855 * @param app The ProcessRecord in which the error occurred.
6856 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6857 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006858 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006859 * @param shortMsg Short message describing the crash.
6860 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006861 * @param stackTrace Full crash stack trace, may be null.
6862 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006863 * @return Returns a fully-formed AppErrorStateInfo record.
6864 */
6865 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006866 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006867 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006868
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006869 report.condition = condition;
6870 report.processName = app.processName;
6871 report.pid = app.pid;
6872 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006873 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006874 report.shortMsg = shortMsg;
6875 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006876 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006877
6878 return report;
6879 }
6880
Dan Egnor42471dd2010-01-07 17:25:22 -08006881 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006882 synchronized (this) {
6883 app.crashing = false;
6884 app.crashingReport = null;
6885 app.notResponding = false;
6886 app.notRespondingReport = null;
6887 if (app.anrDialog == fromDialog) {
6888 app.anrDialog = null;
6889 }
6890 if (app.waitDialog == fromDialog) {
6891 app.waitDialog = null;
6892 }
6893 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006894 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006895 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006896 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6897 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006898 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006900 }
6901 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006902
Dan Egnorb7f03672009-12-09 16:22:32 -08006903 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006904 long now = SystemClock.uptimeMillis();
6905
6906 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6907 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006908 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006909 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006910 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006911 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006912 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006913 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006914 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6915 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006916 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006917 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006918 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006919 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006920 }
6921 }
6922 if (!app.persistent) {
6923 // We don't want to start this process again until the user
6924 // explicitly does so... but for persistent process, we really
6925 // need to keep it running. If a persistent process is actually
6926 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006927 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006928 app.info.processName);
6929 mBadProcesses.put(app.info.processName, app.info.uid, now);
6930 app.bad = true;
6931 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6932 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006933 // Don't let services in this process be restarted and potentially
6934 // annoy the user repeatedly. Unless it is persistent, since those
6935 // processes run critical code.
6936 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006937 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006938 return false;
6939 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006940 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006941 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006942 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006943 if (r.app == app) {
6944 // If the top running activity is from this crashing
6945 // process, then terminate it to avoid getting in a loop.
6946 Slog.w(TAG, " Force finishing activity "
6947 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006948 int index = mMainStack.indexOfTokenLocked(r);
6949 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006950 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006951 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006952 // stopped, to avoid a situation where one will get
6953 // re-start our crashing activity once it gets resumed again.
6954 index--;
6955 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006956 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006957 if (r.state == ActivityState.RESUMED
6958 || r.state == ActivityState.PAUSING
6959 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006960 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006961 Slog.w(TAG, " Force finishing activity "
6962 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006963 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006964 Activity.RESULT_CANCELED, null, "crashed");
6965 }
6966 }
6967 }
6968 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006969 }
6970
6971 // Bump up the crash count of any services currently running in the proc.
6972 if (app.services.size() != 0) {
6973 // Any services running in the application need to be placed
6974 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006975 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006976 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006977 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006978 sr.crashCount++;
6979 }
6980 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006981
6982 // If the crashing process is what we consider to be the "home process" and it has been
6983 // replaced by a third-party app, clear the package preferred activities from packages
6984 // with a home activity running in the process to prevent a repeatedly crashing app
6985 // from blocking the user to manually clear the list.
6986 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6987 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6988 Iterator it = mHomeProcess.activities.iterator();
6989 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006990 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006991 if (r.isHomeActivity) {
6992 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6993 try {
6994 ActivityThread.getPackageManager()
6995 .clearPackagePreferredActivities(r.packageName);
6996 } catch (RemoteException c) {
6997 // pm is in same process, this will never happen.
6998 }
6999 }
7000 }
7001 }
7002
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007003 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7004 return true;
7005 }
7006
7007 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007008 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7009 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007010 skipCurrentReceiverLocked(app);
7011 }
7012
7013 void skipCurrentReceiverLocked(ProcessRecord app) {
7014 boolean reschedule = false;
7015 BroadcastRecord r = app.curReceiver;
7016 if (r != null) {
7017 // The current broadcast is waiting for this app's receiver
7018 // to be finished. Looks like that's not going to happen, so
7019 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007020 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007021 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7022 r.resultExtras, r.resultAbort, true);
7023 reschedule = true;
7024 }
7025 r = mPendingBroadcast;
7026 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007027 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007028 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007029 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007030 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7031 r.resultExtras, r.resultAbort, true);
7032 reschedule = true;
7033 }
7034 if (reschedule) {
7035 scheduleBroadcastsLocked();
7036 }
7037 }
7038
Dan Egnor60d87622009-12-16 16:32:58 -08007039 /**
7040 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7041 * The application process will exit immediately after this call returns.
7042 * @param app object of the crashing app, null for the system server
7043 * @param crashInfo describing the exception
7044 */
7045 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007046 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08007047
7048 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7049 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007050 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007051 crashInfo.exceptionClassName,
7052 crashInfo.exceptionMessage,
7053 crashInfo.throwFileName,
7054 crashInfo.throwLineNumber);
7055
Dan Egnor42471dd2010-01-07 17:25:22 -08007056 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007057
7058 crashApplication(r, crashInfo);
7059 }
7060
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007061 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007062 IBinder app,
7063 int violationMask,
7064 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007065 ProcessRecord r = findAppProcess(app, "StrictMode");
7066 if (r == null) {
7067 return;
7068 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007069
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007070 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007071 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007072 boolean logIt = true;
7073 synchronized (mAlreadyLoggedViolatedStacks) {
7074 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7075 logIt = false;
7076 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007077 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007078 // the relative pain numbers, without logging all
7079 // the stack traces repeatedly. We'd want to do
7080 // likewise in the client code, which also does
7081 // dup suppression, before the Binder call.
7082 } else {
7083 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7084 mAlreadyLoggedViolatedStacks.clear();
7085 }
7086 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7087 }
7088 }
7089 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007090 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007091 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007092 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007093
7094 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7095 AppErrorResult result = new AppErrorResult();
7096 synchronized (this) {
7097 final long origId = Binder.clearCallingIdentity();
7098
7099 Message msg = Message.obtain();
7100 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7101 HashMap<String, Object> data = new HashMap<String, Object>();
7102 data.put("result", result);
7103 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007104 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007105 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007106 msg.obj = data;
7107 mHandler.sendMessage(msg);
7108
7109 Binder.restoreCallingIdentity(origId);
7110 }
7111 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007112 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007113 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007114 }
7115
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007116 // Depending on the policy in effect, there could be a bunch of
7117 // these in quick succession so we try to batch these together to
7118 // minimize disk writes, number of dropbox entries, and maximize
7119 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007120 private void logStrictModeViolationToDropBox(
7121 ProcessRecord process,
7122 StrictMode.ViolationInfo info) {
7123 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007124 return;
7125 }
7126 final boolean isSystemApp = process == null ||
7127 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7128 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7129 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7130 final DropBoxManager dbox = (DropBoxManager)
7131 mContext.getSystemService(Context.DROPBOX_SERVICE);
7132
7133 // Exit early if the dropbox isn't configured to accept this report type.
7134 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7135
7136 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007137 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007138 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7139 synchronized (sb) {
7140 bufferWasEmpty = sb.length() == 0;
7141 appendDropBoxProcessHeaders(process, sb);
7142 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7143 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007144 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7145 if (info.violationNumThisLoop != 0) {
7146 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7147 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007148 if (info.numAnimationsRunning != 0) {
7149 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7150 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007151 if (info.broadcastIntentAction != null) {
7152 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7153 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007154 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007155 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007156 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007157 if (info.numInstances != -1) {
7158 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7159 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007160 if (info.tags != null) {
7161 for (String tag : info.tags) {
7162 sb.append("Span-Tag: ").append(tag).append("\n");
7163 }
7164 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007165 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007166 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7167 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007168 }
7169 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007170
7171 // Only buffer up to ~64k. Various logging bits truncate
7172 // things at 128k.
7173 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007174 }
7175
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007176 // Flush immediately if the buffer's grown too large, or this
7177 // is a non-system app. Non-system apps are isolated with a
7178 // different tag & policy and not batched.
7179 //
7180 // Batching is useful during internal testing with
7181 // StrictMode settings turned up high. Without batching,
7182 // thousands of separate files could be created on boot.
7183 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007184 new Thread("Error dump: " + dropboxTag) {
7185 @Override
7186 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007187 String report;
7188 synchronized (sb) {
7189 report = sb.toString();
7190 sb.delete(0, sb.length());
7191 sb.trimToSize();
7192 }
7193 if (report.length() != 0) {
7194 dbox.addText(dropboxTag, report);
7195 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007196 }
7197 }.start();
7198 return;
7199 }
7200
7201 // System app batching:
7202 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007203 // An existing dropbox-writing thread is outstanding, so
7204 // we don't need to start it up. The existing thread will
7205 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007206 return;
7207 }
7208
7209 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7210 // (After this point, we shouldn't access AMS internal data structures.)
7211 new Thread("Error dump: " + dropboxTag) {
7212 @Override
7213 public void run() {
7214 // 5 second sleep to let stacks arrive and be batched together
7215 try {
7216 Thread.sleep(5000); // 5 seconds
7217 } catch (InterruptedException e) {}
7218
7219 String errorReport;
7220 synchronized (mStrictModeBuffer) {
7221 errorReport = mStrictModeBuffer.toString();
7222 if (errorReport.length() == 0) {
7223 return;
7224 }
7225 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7226 mStrictModeBuffer.trimToSize();
7227 }
7228 dbox.addText(dropboxTag, errorReport);
7229 }
7230 }.start();
7231 }
7232
Dan Egnor60d87622009-12-16 16:32:58 -08007233 /**
7234 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7235 * @param app object of the crashing app, null for the system server
7236 * @param tag reported by the caller
7237 * @param crashInfo describing the context of the error
7238 * @return true if the process should exit immediately (WTF is fatal)
7239 */
7240 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007241 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007242 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007243
7244 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7245 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007246 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007247 tag, crashInfo.exceptionMessage);
7248
Dan Egnor42471dd2010-01-07 17:25:22 -08007249 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007250
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007251 if (r != null && r.pid != Process.myPid() &&
7252 Settings.Secure.getInt(mContext.getContentResolver(),
7253 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007254 crashApplication(r, crashInfo);
7255 return true;
7256 } else {
7257 return false;
7258 }
7259 }
7260
7261 /**
7262 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7263 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7264 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007265 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007266 if (app == null) {
7267 return null;
7268 }
7269
7270 synchronized (this) {
7271 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7272 final int NA = apps.size();
7273 for (int ia=0; ia<NA; ia++) {
7274 ProcessRecord p = apps.valueAt(ia);
7275 if (p.thread != null && p.thread.asBinder() == app) {
7276 return p;
7277 }
7278 }
7279 }
7280
Dianne Hackborncb44d962011-03-10 17:02:27 -08007281 Slog.w(TAG, "Can't find mystery application for " + reason
7282 + " from pid=" + Binder.getCallingPid()
7283 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007284 return null;
7285 }
7286 }
7287
7288 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007289 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7290 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007291 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007292 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007293 // Watchdog thread ends up invoking this function (with
7294 // a null ProcessRecord) to add the stack file to dropbox.
7295 // Do not acquire a lock on this (am) in such cases, as it
7296 // could cause a potential deadlock, if and when watchdog
7297 // is invoked due to unavailability of lock on am and it
7298 // would prevent watchdog from killing system_server.
7299 if (process == null) {
7300 sb.append("Process: system_server\n");
7301 return;
7302 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007303 // Note: ProcessRecord 'process' is guarded by the service
7304 // instance. (notably process.pkgList, which could otherwise change
7305 // concurrently during execution of this method)
7306 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007307 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007308 sb.append("Process: system_server\n");
7309 } else {
7310 sb.append("Process: ").append(process.processName).append("\n");
7311 }
Dan Egnora455d192010-03-12 08:52:28 -08007312 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007313 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007314 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7315 for (String pkg : process.pkgList) {
7316 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007317 try {
Dan Egnora455d192010-03-12 08:52:28 -08007318 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7319 if (pi != null) {
7320 sb.append(" v").append(pi.versionCode);
7321 if (pi.versionName != null) {
7322 sb.append(" (").append(pi.versionName).append(")");
7323 }
7324 }
7325 } catch (RemoteException e) {
7326 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007327 }
Dan Egnora455d192010-03-12 08:52:28 -08007328 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007329 }
Dan Egnora455d192010-03-12 08:52:28 -08007330 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007331 }
7332
7333 private static String processClass(ProcessRecord process) {
7334 if (process == null || process.pid == MY_PID) {
7335 return "system_server";
7336 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7337 return "system_app";
7338 } else {
7339 return "data_app";
7340 }
7341 }
7342
7343 /**
7344 * Write a description of an error (crash, WTF, ANR) to the drop box.
7345 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7346 * @param process which caused the error, null means the system server
7347 * @param activity which triggered the error, null if unknown
7348 * @param parent activity related to the error, null if unknown
7349 * @param subject line related to the error, null if absent
7350 * @param report in long form describing the error, null if absent
7351 * @param logFile to include in the report, null if none
7352 * @param crashInfo giving an application stack trace, null if absent
7353 */
7354 public void addErrorToDropBox(String eventType,
7355 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7356 final String report, final File logFile,
7357 final ApplicationErrorReport.CrashInfo crashInfo) {
7358 // NOTE -- this must never acquire the ActivityManagerService lock,
7359 // otherwise the watchdog may be prevented from resetting the system.
7360
7361 final String dropboxTag = processClass(process) + "_" + eventType;
7362 final DropBoxManager dbox = (DropBoxManager)
7363 mContext.getSystemService(Context.DROPBOX_SERVICE);
7364
7365 // Exit early if the dropbox isn't configured to accept this report type.
7366 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7367
7368 final StringBuilder sb = new StringBuilder(1024);
7369 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007370 if (activity != null) {
7371 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7372 }
7373 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7374 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7375 }
7376 if (parent != null && parent != activity) {
7377 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7378 }
7379 if (subject != null) {
7380 sb.append("Subject: ").append(subject).append("\n");
7381 }
7382 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007383 if (Debug.isDebuggerConnected()) {
7384 sb.append("Debugger: Connected\n");
7385 }
Dan Egnora455d192010-03-12 08:52:28 -08007386 sb.append("\n");
7387
7388 // Do the rest in a worker thread to avoid blocking the caller on I/O
7389 // (After this point, we shouldn't access AMS internal data structures.)
7390 Thread worker = new Thread("Error dump: " + dropboxTag) {
7391 @Override
7392 public void run() {
7393 if (report != null) {
7394 sb.append(report);
7395 }
7396 if (logFile != null) {
7397 try {
7398 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7399 } catch (IOException e) {
7400 Slog.e(TAG, "Error reading " + logFile, e);
7401 }
7402 }
7403 if (crashInfo != null && crashInfo.stackTrace != null) {
7404 sb.append(crashInfo.stackTrace);
7405 }
7406
7407 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7408 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7409 if (lines > 0) {
7410 sb.append("\n");
7411
7412 // Merge several logcat streams, and take the last N lines
7413 InputStreamReader input = null;
7414 try {
7415 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7416 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7417 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7418
7419 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7420 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7421 input = new InputStreamReader(logcat.getInputStream());
7422
7423 int num;
7424 char[] buf = new char[8192];
7425 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7426 } catch (IOException e) {
7427 Slog.e(TAG, "Error running logcat", e);
7428 } finally {
7429 if (input != null) try { input.close(); } catch (IOException e) {}
7430 }
7431 }
7432
7433 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007434 }
Dan Egnora455d192010-03-12 08:52:28 -08007435 };
7436
7437 if (process == null || process.pid == MY_PID) {
7438 worker.run(); // We may be about to die -- need to run this synchronously
7439 } else {
7440 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007441 }
7442 }
7443
7444 /**
7445 * Bring up the "unexpected error" dialog box for a crashing app.
7446 * Deal with edge cases (intercepts from instrumented applications,
7447 * ActivityController, error intent receivers, that sort of thing).
7448 * @param r the application crashing
7449 * @param crashInfo describing the failure
7450 */
7451 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007452 long timeMillis = System.currentTimeMillis();
7453 String shortMsg = crashInfo.exceptionClassName;
7454 String longMsg = crashInfo.exceptionMessage;
7455 String stackTrace = crashInfo.stackTrace;
7456 if (shortMsg != null && longMsg != null) {
7457 longMsg = shortMsg + ": " + longMsg;
7458 } else if (shortMsg != null) {
7459 longMsg = shortMsg;
7460 }
7461
Dan Egnor60d87622009-12-16 16:32:58 -08007462 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007463 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007464 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007465 try {
7466 String name = r != null ? r.processName : null;
7467 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007468 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007469 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007470 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007471 + " at watcher's request");
7472 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007473 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007474 }
7475 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007476 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007477 }
7478 }
7479
7480 final long origId = Binder.clearCallingIdentity();
7481
7482 // If this process is running instrumentation, finish it.
7483 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007484 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007485 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007486 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7487 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007488 Bundle info = new Bundle();
7489 info.putString("shortMsg", shortMsg);
7490 info.putString("longMsg", longMsg);
7491 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7492 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007493 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007494 }
7495
Dan Egnor60d87622009-12-16 16:32:58 -08007496 // If we can't identify the process or it's already exceeded its crash quota,
7497 // quit right away without showing a crash dialog.
7498 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007499 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007500 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007501 }
7502
7503 Message msg = Message.obtain();
7504 msg.what = SHOW_ERROR_MSG;
7505 HashMap data = new HashMap();
7506 data.put("result", result);
7507 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007508 msg.obj = data;
7509 mHandler.sendMessage(msg);
7510
7511 Binder.restoreCallingIdentity(origId);
7512 }
7513
7514 int res = result.get();
7515
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007516 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007517 synchronized (this) {
7518 if (r != null) {
7519 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7520 SystemClock.uptimeMillis());
7521 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007522 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007523 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007524 }
7525 }
7526
7527 if (appErrorIntent != null) {
7528 try {
7529 mContext.startActivity(appErrorIntent);
7530 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007531 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007534 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007535
7536 Intent createAppErrorIntentLocked(ProcessRecord r,
7537 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7538 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007539 if (report == null) {
7540 return null;
7541 }
7542 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7543 result.setComponent(r.errorReportReceiver);
7544 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7545 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7546 return result;
7547 }
7548
Dan Egnorb7f03672009-12-09 16:22:32 -08007549 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7550 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007551 if (r.errorReportReceiver == null) {
7552 return null;
7553 }
7554
7555 if (!r.crashing && !r.notResponding) {
7556 return null;
7557 }
7558
Dan Egnorb7f03672009-12-09 16:22:32 -08007559 ApplicationErrorReport report = new ApplicationErrorReport();
7560 report.packageName = r.info.packageName;
7561 report.installerPackageName = r.errorReportReceiver.getPackageName();
7562 report.processName = r.processName;
7563 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007564 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007565
Dan Egnorb7f03672009-12-09 16:22:32 -08007566 if (r.crashing) {
7567 report.type = ApplicationErrorReport.TYPE_CRASH;
7568 report.crashInfo = crashInfo;
7569 } else if (r.notResponding) {
7570 report.type = ApplicationErrorReport.TYPE_ANR;
7571 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007572
Dan Egnorb7f03672009-12-09 16:22:32 -08007573 report.anrInfo.activity = r.notRespondingReport.tag;
7574 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7575 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007576 }
7577
Dan Egnorb7f03672009-12-09 16:22:32 -08007578 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007579 }
7580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007581 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7582 // assume our apps are happy - lazy create the list
7583 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7584
7585 synchronized (this) {
7586
7587 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007588 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7589 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007590 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7591 // This one's in trouble, so we'll generate a report for it
7592 // crashes are higher priority (in case there's a crash *and* an anr)
7593 ActivityManager.ProcessErrorStateInfo report = null;
7594 if (app.crashing) {
7595 report = app.crashingReport;
7596 } else if (app.notResponding) {
7597 report = app.notRespondingReport;
7598 }
7599
7600 if (report != null) {
7601 if (errList == null) {
7602 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7603 }
7604 errList.add(report);
7605 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007606 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007607 " crashing = " + app.crashing +
7608 " notResponding = " + app.notResponding);
7609 }
7610 }
7611 }
7612 }
7613
7614 return errList;
7615 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007616
7617 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
7618 if (adj >= ProcessList.EMPTY_APP_ADJ) {
7619 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7620 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
7621 if (currApp != null) {
7622 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7623 }
7624 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7625 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7626 if (currApp != null) {
7627 currApp.lru = 0;
7628 }
7629 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7630 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
7631 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7632 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7633 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7634 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7635 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7636 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7637 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7638 } else {
7639 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7640 }
7641 }
7642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007643 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7644 // Lazy instantiation of list
7645 List<ActivityManager.RunningAppProcessInfo> runList = null;
7646 synchronized (this) {
7647 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007648 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7649 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007650 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7651 // Generate process state info for running application
7652 ActivityManager.RunningAppProcessInfo currApp =
7653 new ActivityManager.RunningAppProcessInfo(app.processName,
7654 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007655 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007656 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007657 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007658 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007659 if (app.persistent) {
7660 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7661 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007662 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007663 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007664 currApp.importanceReasonCode = app.adjTypeCode;
7665 if (app.adjSource instanceof ProcessRecord) {
7666 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007667 currApp.importanceReasonImportance = oomAdjToImportance(
7668 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007669 } else if (app.adjSource instanceof ActivityRecord) {
7670 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007671 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7672 }
7673 if (app.adjTarget instanceof ComponentName) {
7674 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7675 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007676 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007677 // + " lru=" + currApp.lru);
7678 if (runList == null) {
7679 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7680 }
7681 runList.add(currApp);
7682 }
7683 }
7684 }
7685 return runList;
7686 }
7687
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007688 public List<ApplicationInfo> getRunningExternalApplications() {
7689 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7690 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7691 if (runningApps != null && runningApps.size() > 0) {
7692 Set<String> extList = new HashSet<String>();
7693 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7694 if (app.pkgList != null) {
7695 for (String pkg : app.pkgList) {
7696 extList.add(pkg);
7697 }
7698 }
7699 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007700 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007701 for (String pkg : extList) {
7702 try {
7703 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7704 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7705 retList.add(info);
7706 }
7707 } catch (RemoteException e) {
7708 }
7709 }
7710 }
7711 return retList;
7712 }
7713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007714 @Override
7715 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007716 if (checkCallingPermission(android.Manifest.permission.DUMP)
7717 != PackageManager.PERMISSION_GRANTED) {
7718 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7719 + Binder.getCallingPid()
7720 + ", uid=" + Binder.getCallingUid()
7721 + " without permission "
7722 + android.Manifest.permission.DUMP);
7723 return;
7724 }
7725
7726 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007727 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007728
7729 int opti = 0;
7730 while (opti < args.length) {
7731 String opt = args[opti];
7732 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7733 break;
7734 }
7735 opti++;
7736 if ("-a".equals(opt)) {
7737 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007738 } else if ("-c".equals(opt)) {
7739 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007740 } else if ("-h".equals(opt)) {
7741 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007742 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007743 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007744 pw.println(" a[ctivities]: activity stack state");
7745 pw.println(" b[roadcasts]: broadcast state");
7746 pw.println(" i[ntents]: pending intent state");
7747 pw.println(" p[rocesses]: process state");
7748 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007749 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7750 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007751 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007752 pw.println(" all: dump all activities");
7753 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007754 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007755 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7756 pw.println(" a partial substring in a component name, a");
7757 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007758 pw.println(" -a: include all available server state.");
7759 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007760 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007761 } else {
7762 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007763 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007764 }
7765
7766 // Is the caller requesting to dump a particular piece of data?
7767 if (opti < args.length) {
7768 String cmd = args[opti];
7769 opti++;
7770 if ("activities".equals(cmd) || "a".equals(cmd)) {
7771 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007772 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007773 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007774 return;
7775 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7776 synchronized (this) {
7777 dumpBroadcastsLocked(fd, pw, args, opti, true);
7778 }
7779 return;
7780 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7781 synchronized (this) {
7782 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7783 }
7784 return;
7785 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7786 synchronized (this) {
7787 dumpProcessesLocked(fd, pw, args, opti, true);
7788 }
7789 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007790 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7791 synchronized (this) {
7792 dumpOomLocked(fd, pw, args, opti, true);
7793 }
7794 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007795 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7796 synchronized (this) {
7797 dumpProvidersLocked(fd, pw, args, opti, true);
7798 }
7799 return;
7800 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007801 String[] newArgs;
7802 String name;
7803 if (opti >= args.length) {
7804 name = null;
7805 newArgs = EMPTY_STRING_ARRAY;
7806 } else {
7807 name = args[opti];
7808 opti++;
7809 newArgs = new String[args.length - opti];
7810 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7811 }
7812 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7813 pw.println("No services match: " + name);
7814 pw.println("Use -h for help.");
7815 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007816 return;
7817 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7818 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007819 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007820 }
7821 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007822 } else {
7823 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007824 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7825 pw.println("Bad activity command, or no activities match: " + cmd);
7826 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007827 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007828 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007829 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007830 }
7831
7832 // No piece of data specified, dump everything.
7833 synchronized (this) {
7834 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007835 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007836 if (needSep) {
7837 pw.println(" ");
7838 }
7839 if (dumpAll) {
7840 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007841 }
7842 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7843 if (needSep) {
7844 pw.println(" ");
7845 }
7846 if (dumpAll) {
7847 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007848 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007849 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007850 if (needSep) {
7851 pw.println(" ");
7852 }
7853 if (dumpAll) {
7854 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007855 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007856 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007857 if (needSep) {
7858 pw.println(" ");
7859 }
7860 if (dumpAll) {
7861 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007862 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007863 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007864 if (needSep) {
7865 pw.println(" ");
7866 }
7867 if (dumpAll) {
7868 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007869 }
7870 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7871 }
7872 }
7873
7874 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007875 int opti, boolean dumpAll, boolean dumpClient) {
7876 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7877 pw.println(" Main stack:");
7878 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007879 pw.println(" ");
7880 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007881 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007882 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007883 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007884 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007885 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7886 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007887 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007888 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007889 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007890 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007891 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7892 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007893 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007894 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7895 pw.println(" ");
7896 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007897 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7898 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007899 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007900 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007901 pw.println(" ");
7902 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007903 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7904 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007906
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007907 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007908 if (mMainStack.mPausingActivity != null) {
7909 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7910 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007911 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007912 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007913 if (dumpAll) {
7914 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7915 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07007916 pw.println(" mDismissKeyguardOnNextActivity: "
7917 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007919
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007920 if (mRecentTasks.size() > 0) {
7921 pw.println();
7922 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007923
7924 final int N = mRecentTasks.size();
7925 for (int i=0; i<N; i++) {
7926 TaskRecord tr = mRecentTasks.get(i);
7927 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7928 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007929 if (dumpAll) {
7930 mRecentTasks.get(i).dump(pw, " ");
7931 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007932 }
7933 }
7934
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007935 if (dumpAll) {
7936 pw.println(" ");
7937 pw.println(" mCurTask: " + mCurTask);
7938 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007939
7940 return true;
7941 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007942
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007943 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7944 int opti, boolean dumpAll) {
7945 boolean needSep = false;
7946 int numPers = 0;
7947
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007948 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7949
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007950 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007951 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7952 final int NA = procs.size();
7953 for (int ia=0; ia<NA; ia++) {
7954 if (!needSep) {
7955 pw.println(" All known processes:");
7956 needSep = true;
7957 }
7958 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007959 pw.print(r.persistent ? " *PERS*" : " *APP*");
7960 pw.print(" UID "); pw.print(procs.keyAt(ia));
7961 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007962 r.dump(pw, " ");
7963 if (r.persistent) {
7964 numPers++;
7965 }
7966 }
7967 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007968 }
7969
7970 if (mLruProcesses.size() > 0) {
7971 if (needSep) pw.println(" ");
7972 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007973 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007974 dumpProcessOomList(pw, this, mLruProcesses, " ",
7975 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007976 needSep = true;
7977 }
7978
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007979 if (dumpAll) {
7980 synchronized (mPidsSelfLocked) {
7981 if (mPidsSelfLocked.size() > 0) {
7982 if (needSep) pw.println(" ");
7983 needSep = true;
7984 pw.println(" PID mappings:");
7985 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7986 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7987 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007989 }
7990 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007991 }
7992
7993 if (mForegroundProcesses.size() > 0) {
7994 if (needSep) pw.println(" ");
7995 needSep = true;
7996 pw.println(" Foreground Processes:");
7997 for (int i=0; i<mForegroundProcesses.size(); i++) {
7998 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7999 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008000 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008001 }
8002
8003 if (mPersistentStartingProcesses.size() > 0) {
8004 if (needSep) pw.println(" ");
8005 needSep = true;
8006 pw.println(" Persisent processes that are starting:");
8007 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008008 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008009 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008010
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008011 if (mRemovedProcesses.size() > 0) {
8012 if (needSep) pw.println(" ");
8013 needSep = true;
8014 pw.println(" Processes that are being removed:");
8015 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008016 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008017 }
8018
8019 if (mProcessesOnHold.size() > 0) {
8020 if (needSep) pw.println(" ");
8021 needSep = true;
8022 pw.println(" Processes that are on old until the system is ready:");
8023 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008024 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008026
Dianne Hackborn287952c2010-09-22 22:34:31 -07008027 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008028
8029 if (mProcessCrashTimes.getMap().size() > 0) {
8030 if (needSep) pw.println(" ");
8031 needSep = true;
8032 pw.println(" Time since processes crashed:");
8033 long now = SystemClock.uptimeMillis();
8034 for (Map.Entry<String, SparseArray<Long>> procs
8035 : mProcessCrashTimes.getMap().entrySet()) {
8036 SparseArray<Long> uids = procs.getValue();
8037 final int N = uids.size();
8038 for (int i=0; i<N; i++) {
8039 pw.print(" Process "); pw.print(procs.getKey());
8040 pw.print(" uid "); pw.print(uids.keyAt(i));
8041 pw.print(": last crashed ");
8042 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008043 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008044 }
8045 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008047
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008048 if (mBadProcesses.getMap().size() > 0) {
8049 if (needSep) pw.println(" ");
8050 needSep = true;
8051 pw.println(" Bad processes:");
8052 for (Map.Entry<String, SparseArray<Long>> procs
8053 : mBadProcesses.getMap().entrySet()) {
8054 SparseArray<Long> uids = procs.getValue();
8055 final int N = uids.size();
8056 for (int i=0; i<N; i++) {
8057 pw.print(" Bad process "); pw.print(procs.getKey());
8058 pw.print(" uid "); pw.print(uids.keyAt(i));
8059 pw.print(": crashed at time ");
8060 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008061 }
8062 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008063 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008064
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008065 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008066 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008067 if (mHeavyWeightProcess != null) {
8068 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8069 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008070 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008071 if (dumpAll) {
8072 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008073 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008074 pw.println(" mScreenCompatPackages:");
8075 for (Map.Entry<String, Integer> entry
8076 : mCompatModePackages.getPackages().entrySet()) {
8077 String pkg = entry.getKey();
8078 int mode = entry.getValue();
8079 pw.print(" "); pw.print(pkg); pw.print(": ");
8080 pw.print(mode); pw.println();
8081 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008082 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008083 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008084 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8085 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8086 || mOrigWaitForDebugger) {
8087 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8088 + " mDebugTransient=" + mDebugTransient
8089 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8090 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008091 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8092 || mProfileFd != null) {
8093 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8094 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8095 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8096 + mAutoStopProfiler);
8097 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008098 if (mAlwaysFinishActivities || mController != null) {
8099 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8100 + " mController=" + mController);
8101 }
8102 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008103 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008104 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008105 + " mProcessesReady=" + mProcessesReady
8106 + " mSystemReady=" + mSystemReady);
8107 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008108 + " mBooted=" + mBooted
8109 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008110 pw.print(" mLastPowerCheckRealtime=");
8111 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8112 pw.println("");
8113 pw.print(" mLastPowerCheckUptime=");
8114 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8115 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008116 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8117 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008118 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008119 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008120
8121 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008122 }
8123
Dianne Hackborn287952c2010-09-22 22:34:31 -07008124 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8125 int opti, boolean needSep, boolean dumpAll) {
8126 if (mProcessesToGc.size() > 0) {
8127 if (needSep) pw.println(" ");
8128 needSep = true;
8129 pw.println(" Processes that are waiting to GC:");
8130 long now = SystemClock.uptimeMillis();
8131 for (int i=0; i<mProcessesToGc.size(); i++) {
8132 ProcessRecord proc = mProcessesToGc.get(i);
8133 pw.print(" Process "); pw.println(proc);
8134 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8135 pw.print(", last gced=");
8136 pw.print(now-proc.lastRequestedGc);
8137 pw.print(" ms ago, last lowMem=");
8138 pw.print(now-proc.lastLowMemory);
8139 pw.println(" ms ago");
8140
8141 }
8142 }
8143 return needSep;
8144 }
8145
8146 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8147 int opti, boolean dumpAll) {
8148 boolean needSep = false;
8149
8150 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008151 if (needSep) pw.println(" ");
8152 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008153 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008154 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8155 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
8156 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8157 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8158 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8159 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8160 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8161 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
8162 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8163 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8164 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008165
8166 if (needSep) pw.println(" ");
8167 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008168 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008169 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008170 "Proc", "PERS", true);
8171 needSep = true;
8172 }
8173
8174 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8175
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008176 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008177 pw.println(" mHomeProcess: " + mHomeProcess);
8178 if (mHeavyWeightProcess != null) {
8179 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8180 }
8181
8182 return true;
8183 }
8184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008185 /**
8186 * There are three ways to call this:
8187 * - no service specified: dump all the services
8188 * - a flattened component name that matched an existing service was specified as the
8189 * first arg: dump that one service
8190 * - the first arg isn't the flattened component name of an existing service:
8191 * dump all services whose component contains the first arg as a substring
8192 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008193 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8194 int opti, boolean dumpAll) {
8195 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008196
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008197 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008198 synchronized (this) {
8199 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008200 services.add(r1);
8201 }
8202 }
8203 } else {
8204 ComponentName componentName = name != null
8205 ? ComponentName.unflattenFromString(name) : null;
8206 int objectId = 0;
8207 if (componentName == null) {
8208 // Not a '/' separated full component name; maybe an object ID?
8209 try {
8210 objectId = Integer.parseInt(name, 16);
8211 name = null;
8212 componentName = null;
8213 } catch (RuntimeException e) {
8214 }
8215 }
8216
8217 synchronized (this) {
8218 for (ServiceRecord r1 : mServices.values()) {
8219 if (componentName != null) {
8220 if (r1.name.equals(componentName)) {
8221 services.add(r1);
8222 }
8223 } else if (name != null) {
8224 if (r1.name.flattenToString().contains(name)) {
8225 services.add(r1);
8226 }
8227 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008228 services.add(r1);
8229 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008230 }
8231 }
8232 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008233
8234 if (services.size() <= 0) {
8235 return false;
8236 }
8237
8238 boolean needSep = false;
8239 for (int i=0; i<services.size(); i++) {
8240 if (needSep) {
8241 pw.println();
8242 }
8243 needSep = true;
8244 dumpService("", fd, pw, services.get(i), args, dumpAll);
8245 }
8246 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008247 }
8248
8249 /**
8250 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8251 * there is a thread associated with the service.
8252 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008253 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8254 final ServiceRecord r, String[] args, boolean dumpAll) {
8255 String innerPrefix = prefix + " ";
8256 synchronized (this) {
8257 pw.print(prefix); pw.print("SERVICE ");
8258 pw.print(r.shortName); pw.print(" ");
8259 pw.print(Integer.toHexString(System.identityHashCode(r)));
8260 pw.print(" pid=");
8261 if (r.app != null) pw.println(r.app.pid);
8262 else pw.println("(not running)");
8263 if (dumpAll) {
8264 r.dump(pw, innerPrefix);
8265 }
8266 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008267 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008268 pw.print(prefix); pw.println(" Client:");
8269 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008270 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008271 TransferPipe tp = new TransferPipe();
8272 try {
8273 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8274 tp.setBufferPrefix(prefix + " ");
8275 tp.go(fd);
8276 } finally {
8277 tp.kill();
8278 }
8279 } catch (IOException e) {
8280 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008281 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008282 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008283 }
8284 }
8285 }
8286
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008287 static class ItemMatcher {
8288 ArrayList<ComponentName> components;
8289 ArrayList<String> strings;
8290 ArrayList<Integer> objects;
8291 boolean all;
8292
8293 ItemMatcher() {
8294 all = true;
8295 }
8296
8297 void build(String name) {
8298 ComponentName componentName = ComponentName.unflattenFromString(name);
8299 if (componentName != null) {
8300 if (components == null) {
8301 components = new ArrayList<ComponentName>();
8302 }
8303 components.add(componentName);
8304 all = false;
8305 } else {
8306 int objectId = 0;
8307 // Not a '/' separated full component name; maybe an object ID?
8308 try {
8309 objectId = Integer.parseInt(name, 16);
8310 if (objects == null) {
8311 objects = new ArrayList<Integer>();
8312 }
8313 objects.add(objectId);
8314 all = false;
8315 } catch (RuntimeException e) {
8316 // Not an integer; just do string match.
8317 if (strings == null) {
8318 strings = new ArrayList<String>();
8319 }
8320 strings.add(name);
8321 all = false;
8322 }
8323 }
8324 }
8325
8326 int build(String[] args, int opti) {
8327 for (; opti<args.length; opti++) {
8328 String name = args[opti];
8329 if ("--".equals(name)) {
8330 return opti+1;
8331 }
8332 build(name);
8333 }
8334 return opti;
8335 }
8336
8337 boolean match(Object object, ComponentName comp) {
8338 if (all) {
8339 return true;
8340 }
8341 if (components != null) {
8342 for (int i=0; i<components.size(); i++) {
8343 if (components.get(i).equals(comp)) {
8344 return true;
8345 }
8346 }
8347 }
8348 if (objects != null) {
8349 for (int i=0; i<objects.size(); i++) {
8350 if (System.identityHashCode(object) == objects.get(i)) {
8351 return true;
8352 }
8353 }
8354 }
8355 if (strings != null) {
8356 String flat = comp.flattenToString();
8357 for (int i=0; i<strings.size(); i++) {
8358 if (flat.contains(strings.get(i))) {
8359 return true;
8360 }
8361 }
8362 }
8363 return false;
8364 }
8365 }
8366
Dianne Hackborn625ac272010-09-17 18:29:22 -07008367 /**
8368 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008369 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008370 * - the cmd arg isn't the flattened component name of an existing activity:
8371 * dump all activity whose component contains the cmd as a substring
8372 * - A hex number of the ActivityRecord object instance.
8373 */
8374 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8375 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008376 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008377
8378 if ("all".equals(name)) {
8379 synchronized (this) {
8380 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008381 activities.add(r1);
8382 }
8383 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008384 } else if ("top".equals(name)) {
8385 synchronized (this) {
8386 final int N = mMainStack.mHistory.size();
8387 if (N > 0) {
8388 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8389 }
8390 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008391 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008392 ItemMatcher matcher = new ItemMatcher();
8393 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008394
8395 synchronized (this) {
8396 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008397 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008398 activities.add(r1);
8399 }
8400 }
8401 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008402 }
8403
8404 if (activities.size() <= 0) {
8405 return false;
8406 }
8407
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008408 String[] newArgs = new String[args.length - opti];
8409 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8410
Dianne Hackborn30d71892010-12-11 10:37:55 -08008411 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008412 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008413 for (int i=activities.size()-1; i>=0; i--) {
8414 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008415 if (needSep) {
8416 pw.println();
8417 }
8418 needSep = true;
8419 synchronized (this) {
8420 if (lastTask != r.task) {
8421 lastTask = r.task;
8422 pw.print("TASK "); pw.print(lastTask.affinity);
8423 pw.print(" id="); pw.println(lastTask.taskId);
8424 if (dumpAll) {
8425 lastTask.dump(pw, " ");
8426 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008427 }
8428 }
8429 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008430 }
8431 return true;
8432 }
8433
8434 /**
8435 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8436 * there is a thread associated with the activity.
8437 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008438 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008439 final ActivityRecord r, String[] args, boolean dumpAll) {
8440 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008441 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008442 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8443 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8444 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008445 if (r.app != null) pw.println(r.app.pid);
8446 else pw.println("(not running)");
8447 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008448 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008449 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008450 }
8451 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008452 // flush anything that is already in the PrintWriter since the thread is going
8453 // to write to the file descriptor directly
8454 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008455 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008456 TransferPipe tp = new TransferPipe();
8457 try {
8458 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8459 innerPrefix, args);
8460 tp.go(fd);
8461 } finally {
8462 tp.kill();
8463 }
8464 } catch (IOException e) {
8465 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008466 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008467 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008468 }
8469 }
8470 }
8471
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008472 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8473 int opti, boolean dumpAll) {
8474 boolean needSep = false;
8475
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008476 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008477 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008478 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008479 pw.println(" Registered Receivers:");
8480 Iterator it = mRegisteredReceivers.values().iterator();
8481 while (it.hasNext()) {
8482 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008483 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008484 r.dump(pw, " ");
8485 }
8486 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008487
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008488 pw.println();
8489 pw.println(" Receiver Resolver Table:");
8490 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008491 needSep = true;
8492 }
8493
8494 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8495 || mPendingBroadcast != null) {
8496 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008497 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008498 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008499 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008500 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8501 pw.println(" Broadcast #" + i + ":");
8502 mParallelBroadcasts.get(i).dump(pw, " ");
8503 }
8504 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008505 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008506 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008507 }
8508 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8509 pw.println(" Serialized Broadcast #" + i + ":");
8510 mOrderedBroadcasts.get(i).dump(pw, " ");
8511 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008512 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008513 pw.println(" Pending broadcast:");
8514 if (mPendingBroadcast != null) {
8515 mPendingBroadcast.dump(pw, " ");
8516 } else {
8517 pw.println(" (null)");
8518 }
8519 needSep = true;
8520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008521
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008522 if (needSep) {
8523 pw.println();
8524 }
8525 pw.println(" Historical broadcasts:");
8526 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8527 BroadcastRecord r = mBroadcastHistory[i];
8528 if (r == null) {
8529 break;
8530 }
8531 if (dumpAll) {
8532 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8533 r.dump(pw, " ");
8534 } else {
8535 if (i >= 50) {
8536 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008537 break;
8538 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008539 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008540 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008541 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008542 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008543
8544 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008545 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008546 pw.println(" Sticky broadcasts:");
8547 StringBuilder sb = new StringBuilder(128);
8548 for (Map.Entry<String, ArrayList<Intent>> ent
8549 : mStickyBroadcasts.entrySet()) {
8550 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008551 if (dumpAll) {
8552 pw.println(":");
8553 ArrayList<Intent> intents = ent.getValue();
8554 final int N = intents.size();
8555 for (int i=0; i<N; i++) {
8556 sb.setLength(0);
8557 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008558 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008559 pw.println(sb.toString());
8560 Bundle bundle = intents.get(i).getExtras();
8561 if (bundle != null) {
8562 pw.print(" ");
8563 pw.println(bundle.toString());
8564 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008565 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008566 } else {
8567 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008568 }
8569 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008570 needSep = true;
8571 }
8572
8573 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008574 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008575 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008576 pw.println(" mHandler:");
8577 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008578 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008579 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008580
8581 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008582 }
8583
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008584 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008585 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008586 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008587
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008588 ItemMatcher matcher = new ItemMatcher();
8589 matcher.build(args, opti);
8590
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008591 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8592 if (mServices.size() > 0) {
8593 pw.println(" Active services:");
8594 long nowReal = SystemClock.elapsedRealtime();
8595 Iterator<ServiceRecord> it = mServices.values().iterator();
8596 needSep = false;
8597 while (it.hasNext()) {
8598 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008599 if (!matcher.match(r, r.name)) {
8600 continue;
8601 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008602 if (needSep) {
8603 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008604 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008605 pw.print(" * "); pw.println(r);
8606 if (dumpAll) {
8607 r.dump(pw, " ");
8608 needSep = true;
8609 } else {
8610 pw.print(" app="); pw.println(r.app);
8611 pw.print(" created=");
8612 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8613 pw.print(" started="); pw.print(r.startRequested);
8614 pw.print(" connections="); pw.println(r.connections.size());
8615 }
8616 if (dumpClient && r.app != null && r.app.thread != null) {
8617 pw.println(" Client:");
8618 pw.flush();
8619 try {
8620 TransferPipe tp = new TransferPipe();
8621 try {
8622 r.app.thread.dumpService(
8623 tp.getWriteFd().getFileDescriptor(), r, args);
8624 tp.setBufferPrefix(" ");
8625 // Short timeout, since blocking here can
8626 // deadlock with the application.
8627 tp.go(fd, 2000);
8628 } finally {
8629 tp.kill();
8630 }
8631 } catch (IOException e) {
8632 pw.println(" Failure while dumping the service: " + e);
8633 } catch (RemoteException e) {
8634 pw.println(" Got a RemoteException while dumping the service");
8635 }
8636 needSep = true;
8637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008638 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008639 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008640 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008641
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008642 if (mPendingServices.size() > 0) {
8643 if (needSep) pw.println(" ");
8644 pw.println(" Pending services:");
8645 for (int i=0; i<mPendingServices.size(); i++) {
8646 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008647 if (!matcher.match(r, r.name)) {
8648 continue;
8649 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008650 pw.print(" * Pending "); pw.println(r);
8651 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008652 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008653 needSep = true;
8654 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008655
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008656 if (mRestartingServices.size() > 0) {
8657 if (needSep) pw.println(" ");
8658 pw.println(" Restarting services:");
8659 for (int i=0; i<mRestartingServices.size(); i++) {
8660 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008661 if (!matcher.match(r, r.name)) {
8662 continue;
8663 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008664 pw.print(" * Restarting "); pw.println(r);
8665 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008666 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008667 needSep = true;
8668 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008669
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008670 if (mStoppingServices.size() > 0) {
8671 if (needSep) pw.println(" ");
8672 pw.println(" Stopping services:");
8673 for (int i=0; i<mStoppingServices.size(); i++) {
8674 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008675 if (!matcher.match(r, r.name)) {
8676 continue;
8677 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008678 pw.print(" * Stopping "); pw.println(r);
8679 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008680 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008681 needSep = true;
8682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008683
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008684 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008685 if (mServiceConnections.size() > 0) {
8686 if (needSep) pw.println(" ");
8687 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008688 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008689 = mServiceConnections.values().iterator();
8690 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008691 ArrayList<ConnectionRecord> r = it.next();
8692 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008693 ConnectionRecord cr = r.get(i);
8694 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8695 continue;
8696 }
8697 pw.print(" * "); pw.println(cr);
8698 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008699 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008700 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008701 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008702 }
8703 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008704
8705 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008706 }
8707
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008708 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8709 int opti, boolean dumpAll) {
8710 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008711
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008712 ItemMatcher matcher = new ItemMatcher();
8713 matcher.build(args, opti);
8714
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008715 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8716 if (mProvidersByClass.size() > 0) {
8717 if (needSep) pw.println(" ");
8718 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008719 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008720 = mProvidersByClass.entrySet().iterator();
8721 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008722 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008723 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008724 ComponentName comp = e.getKey();
8725 String cls = comp.getClassName();
8726 int end = cls.lastIndexOf('.');
8727 if (end > 0 && end < (cls.length()-2)) {
8728 cls = cls.substring(end+1);
8729 }
8730 if (!matcher.match(r, comp)) {
8731 continue;
8732 }
8733 pw.print(" * "); pw.print(cls); pw.print(" (");
8734 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008735 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008736 pw.println();
8737 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008738 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008739 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008740 if (r.proc != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008741 pw.println(":");
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008742 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008743 } else {
8744 pw.println();
8745 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008746 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008747 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008748 needSep = true;
8749 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008750
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008751 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008752 if (mProvidersByName.size() > 0) {
8753 pw.println(" ");
8754 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008755 Iterator<Map.Entry<String, ContentProviderRecord>> it
8756 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008757 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008758 Map.Entry<String, ContentProviderRecord> e = it.next();
8759 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008760 if (!matcher.match(r, r.name)) {
8761 continue;
8762 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008763 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8764 pw.println(r);
8765 }
8766 needSep = true;
8767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008768 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008769
8770 if (mLaunchingProviders.size() > 0) {
8771 if (needSep) pw.println(" ");
8772 pw.println(" Launching content providers:");
8773 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8774 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8775 pw.println(mLaunchingProviders.get(i));
8776 }
8777 needSep = true;
8778 }
8779
8780 if (mGrantedUriPermissions.size() > 0) {
8781 pw.println();
8782 pw.println("Granted Uri Permissions:");
8783 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8784 int uid = mGrantedUriPermissions.keyAt(i);
8785 HashMap<Uri, UriPermission> perms
8786 = mGrantedUriPermissions.valueAt(i);
8787 pw.print(" * UID "); pw.print(uid);
8788 pw.println(" holds:");
8789 for (UriPermission perm : perms.values()) {
8790 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008791 if (dumpAll) {
8792 perm.dump(pw, " ");
8793 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008794 }
8795 }
8796 needSep = true;
8797 }
8798
8799 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008800 }
8801
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008802 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8803 int opti, boolean dumpAll) {
8804 boolean needSep = false;
8805
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008806 if (this.mIntentSenderRecords.size() > 0) {
8807 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8808 Iterator<WeakReference<PendingIntentRecord>> it
8809 = mIntentSenderRecords.values().iterator();
8810 while (it.hasNext()) {
8811 WeakReference<PendingIntentRecord> ref = it.next();
8812 PendingIntentRecord rec = ref != null ? ref.get(): null;
8813 needSep = true;
8814 if (rec != null) {
8815 pw.print(" * "); pw.println(rec);
8816 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008817 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008818 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008819 } else {
8820 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008821 }
8822 }
8823 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008824
8825 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008826 }
8827
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008828 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8829 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008830 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008831 boolean needNL = false;
8832 final String innerPrefix = prefix + " ";
8833 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008834 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008835 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008836 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008837 if (needNL) {
8838 pw.println(" ");
8839 needNL = false;
8840 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008841 if (lastTask != r.task) {
8842 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008843 pw.print(prefix);
8844 pw.print(full ? "* " : " ");
8845 pw.println(lastTask);
8846 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008847 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008848 } else if (complete) {
8849 // Complete + brief == give a summary. Isn't that obvious?!?
8850 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008851 pw.print(prefix); pw.print(" ");
8852 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008853 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008855 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008856 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8857 pw.print(" #"); pw.print(i); pw.print(": ");
8858 pw.println(r);
8859 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008860 r.dump(pw, innerPrefix);
8861 } else if (complete) {
8862 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008863 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008864 if (r.app != null) {
8865 pw.print(innerPrefix); pw.println(r.app);
8866 }
8867 }
8868 if (client && r.app != null && r.app.thread != null) {
8869 // flush anything that is already in the PrintWriter since the thread is going
8870 // to write to the file descriptor directly
8871 pw.flush();
8872 try {
8873 TransferPipe tp = new TransferPipe();
8874 try {
8875 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8876 innerPrefix, args);
8877 // Short timeout, since blocking here can
8878 // deadlock with the application.
8879 tp.go(fd, 2000);
8880 } finally {
8881 tp.kill();
8882 }
8883 } catch (IOException e) {
8884 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8885 } catch (RemoteException e) {
8886 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8887 }
8888 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008889 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008890 }
8891 }
8892
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008893 private static String buildOomTag(String prefix, String space, int val, int base) {
8894 if (val == base) {
8895 if (space == null) return prefix;
8896 return prefix + " ";
8897 }
8898 return prefix + "+" + Integer.toString(val-base);
8899 }
8900
8901 private static final int dumpProcessList(PrintWriter pw,
8902 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008903 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008904 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008905 final int N = list.size()-1;
8906 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008907 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008908 pw.println(String.format("%s%s #%2d: %s",
8909 prefix, (r.persistent ? persistentLabel : normalLabel),
8910 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008911 if (r.persistent) {
8912 numPers++;
8913 }
8914 }
8915 return numPers;
8916 }
8917
Dianne Hackborn287952c2010-09-22 22:34:31 -07008918 private static final void dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07008919 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008920 String prefix, String normalLabel, String persistentLabel,
8921 boolean inclDetails) {
8922
Dianne Hackborn905577f2011-09-07 18:31:28 -07008923 ArrayList<Pair<ProcessRecord, Integer>> list
8924 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
8925 for (int i=0; i<origList.size(); i++) {
8926 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
8927 }
8928
8929 Comparator<Pair<ProcessRecord, Integer>> comparator
8930 = new Comparator<Pair<ProcessRecord, Integer>>() {
8931 @Override
8932 public int compare(Pair<ProcessRecord, Integer> object1,
8933 Pair<ProcessRecord, Integer> object2) {
8934 if (object1.first.setAdj != object2.first.setAdj) {
8935 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
8936 }
8937 if (object1.second.intValue() != object2.second.intValue()) {
8938 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
8939 }
8940 return 0;
8941 }
8942 };
8943
8944 Collections.sort(list, comparator);
8945
Dianne Hackborn287952c2010-09-22 22:34:31 -07008946 final long curRealtime = SystemClock.elapsedRealtime();
8947 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8948 final long curUptime = SystemClock.uptimeMillis();
8949 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8950
8951 final int N = list.size()-1;
8952 for (int i=N; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008953 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008954 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008955 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8956 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8957 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8958 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
8959 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
8960 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
8961 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
8962 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
8963 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
8964 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
8965 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8966 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
8967 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8968 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
8969 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
8970 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
8971 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
8972 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
8973 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
8974 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
8975 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
8976 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008977 } else {
8978 oomAdj = Integer.toString(r.setAdj);
8979 }
8980 String schedGroup;
8981 switch (r.setSchedGroup) {
8982 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8983 schedGroup = "B";
8984 break;
8985 case Process.THREAD_GROUP_DEFAULT:
8986 schedGroup = "F";
8987 break;
8988 default:
8989 schedGroup = Integer.toString(r.setSchedGroup);
8990 break;
8991 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008992 String foreground;
8993 if (r.foregroundActivities) {
8994 foreground = "A";
8995 } else if (r.foregroundServices) {
8996 foreground = "S";
8997 } else {
8998 foreground = " ";
8999 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009000 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009001 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackborn905577f2011-09-07 18:31:28 -07009002 N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009003 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009004 if (r.adjSource != null || r.adjTarget != null) {
9005 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009006 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009007 if (r.adjTarget instanceof ComponentName) {
9008 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9009 } else if (r.adjTarget != null) {
9010 pw.print(r.adjTarget.toString());
9011 } else {
9012 pw.print("{null}");
9013 }
9014 pw.print("<=");
9015 if (r.adjSource instanceof ProcessRecord) {
9016 pw.print("Proc{");
9017 pw.print(((ProcessRecord)r.adjSource).toShortString());
9018 pw.println("}");
9019 } else if (r.adjSource != null) {
9020 pw.println(r.adjSource.toString());
9021 } else {
9022 pw.println("{null}");
9023 }
9024 }
9025 if (inclDetails) {
9026 pw.print(prefix);
9027 pw.print(" ");
9028 pw.print("oom: max="); pw.print(r.maxAdj);
9029 pw.print(" hidden="); pw.print(r.hiddenAdj);
9030 pw.print(" curRaw="); pw.print(r.curRawAdj);
9031 pw.print(" setRaw="); pw.print(r.setRawAdj);
9032 pw.print(" cur="); pw.print(r.curAdj);
9033 pw.print(" set="); pw.println(r.setAdj);
9034 pw.print(prefix);
9035 pw.print(" ");
9036 pw.print("keeping="); pw.print(r.keeping);
9037 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009038 pw.print(" empty="); pw.print(r.empty);
9039 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009040
9041 if (!r.keeping) {
9042 if (r.lastWakeTime != 0) {
9043 long wtime;
9044 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9045 synchronized (stats) {
9046 wtime = stats.getProcessWakeTime(r.info.uid,
9047 r.pid, curRealtime);
9048 }
9049 long timeUsed = wtime - r.lastWakeTime;
9050 pw.print(prefix);
9051 pw.print(" ");
9052 pw.print("keep awake over ");
9053 TimeUtils.formatDuration(realtimeSince, pw);
9054 pw.print(" used ");
9055 TimeUtils.formatDuration(timeUsed, pw);
9056 pw.print(" (");
9057 pw.print((timeUsed*100)/realtimeSince);
9058 pw.println("%)");
9059 }
9060 if (r.lastCpuTime != 0) {
9061 long timeUsed = r.curCpuTime - r.lastCpuTime;
9062 pw.print(prefix);
9063 pw.print(" ");
9064 pw.print("run cpu over ");
9065 TimeUtils.formatDuration(uptimeSince, pw);
9066 pw.print(" used ");
9067 TimeUtils.formatDuration(timeUsed, pw);
9068 pw.print(" (");
9069 pw.print((timeUsed*100)/uptimeSince);
9070 pw.println("%)");
9071 }
9072 }
9073 }
9074 }
9075 }
9076
Dianne Hackbornb437e092011-08-05 17:50:29 -07009077 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009078 ArrayList<ProcessRecord> procs;
9079 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009080 if (args != null && args.length > start
9081 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009082 procs = new ArrayList<ProcessRecord>();
9083 int pid = -1;
9084 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009085 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009086 } catch (NumberFormatException e) {
9087
9088 }
9089 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9090 ProcessRecord proc = mLruProcesses.get(i);
9091 if (proc.pid == pid) {
9092 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009093 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009094 procs.add(proc);
9095 }
9096 }
9097 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009098 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009099 return null;
9100 }
9101 } else {
9102 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9103 }
9104 }
9105 return procs;
9106 }
9107
9108 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9109 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009110 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009111 if (procs == null) {
9112 return;
9113 }
9114
9115 long uptime = SystemClock.uptimeMillis();
9116 long realtime = SystemClock.elapsedRealtime();
9117 pw.println("Applications Graphics Acceleration Info:");
9118 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9119
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009120 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9121 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009122 if (r.thread != null) {
9123 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9124 pw.flush();
9125 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009126 TransferPipe tp = new TransferPipe();
9127 try {
9128 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9129 tp.go(fd);
9130 } finally {
9131 tp.kill();
9132 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009133 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009134 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009135 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009136 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009137 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009138 pw.flush();
9139 }
9140 }
9141 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009142 }
9143
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009144 final static class MemItem {
9145 final String label;
9146 final long pss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009147 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009148
9149 public MemItem(String _label, long _pss) {
9150 label = _label;
9151 pss = _pss;
9152 }
9153 }
9154
Dianne Hackbornb437e092011-08-05 17:50:29 -07009155 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9156 boolean sort) {
9157 if (sort) {
9158 Collections.sort(items, new Comparator<MemItem>() {
9159 @Override
9160 public int compare(MemItem lhs, MemItem rhs) {
9161 if (lhs.pss < rhs.pss) {
9162 return 1;
9163 } else if (lhs.pss > rhs.pss) {
9164 return -1;
9165 }
9166 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009167 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009168 });
9169 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009170
9171 for (int i=0; i<items.size(); i++) {
9172 MemItem mi = items.get(i);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009173 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
9174 if (mi.subitems != null) {
9175 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9176 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009177 }
9178 }
9179
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009180 final void dumpApplicationMemoryUsage(FileDescriptor fd,
9181 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009182 boolean dumpAll = false;
9183
9184 int opti = 0;
9185 while (opti < args.length) {
9186 String opt = args[opti];
9187 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9188 break;
9189 }
9190 opti++;
9191 if ("-a".equals(opt)) {
9192 dumpAll = true;
9193 } else if ("-h".equals(opt)) {
9194 pw.println("meminfo dump options: [-a] [process]");
9195 pw.println(" -a: include all available information for each process.");
9196 pw.println("If [process] is specified it can be the name or ");
9197 pw.println("pid of a specific process to dump.");
9198 return;
9199 } else {
9200 pw.println("Unknown argument: " + opt + "; use -h for help");
9201 }
9202 }
9203
9204 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009205 if (procs == null) {
9206 return;
9207 }
9208
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009209 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009210 long uptime = SystemClock.uptimeMillis();
9211 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009212
9213 if (procs.size() == 1 || isCheckinRequest) {
9214 dumpAll = true;
9215 }
9216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009217 if (isCheckinRequest) {
9218 // short checkin version
9219 pw.println(uptime + "," + realtime);
9220 pw.flush();
9221 } else {
9222 pw.println("Applications Memory Usage (kB):");
9223 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9224 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009225
Dianne Hackbornb437e092011-08-05 17:50:29 -07009226 String[] innerArgs = new String[args.length-opti];
9227 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9228
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009229 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9230 long nativePss=0, dalvikPss=0, otherPss=0;
9231 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9232
Dianne Hackbornb437e092011-08-05 17:50:29 -07009233 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009234 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9235 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9236 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009237 };
9238 final String[] oomLabel = new String[] {
9239 "System", "Persistent", "Foreground",
9240 "Visible", "Perceptible", "Heavy Weight",
9241 "Backup", "Services", "Home", "Background"
9242 };
9243 long oomPss[] = new long[oomLabel.length];
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009244 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009245
9246 long totalPss = 0;
9247
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009248 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9249 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009250 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009251 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009252 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9253 pw.flush();
9254 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009255 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009256 if (dumpAll) {
9257 try {
9258 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9259 } catch (RemoteException e) {
9260 if (!isCheckinRequest) {
9261 pw.println("Got RemoteException!");
9262 pw.flush();
9263 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009264 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009265 } else {
9266 mi = new Debug.MemoryInfo();
9267 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009268 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009269
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009270 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009271 long myTotalPss = mi.getTotalPss();
9272 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009273 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9274 myTotalPss);
9275 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009276
9277 nativePss += mi.nativePss;
9278 dalvikPss += mi.dalvikPss;
9279 otherPss += mi.otherPss;
9280 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9281 long mem = mi.getOtherPss(j);
9282 miscPss[j] += mem;
9283 otherPss -= mem;
9284 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009285
9286 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9287 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9288 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009289 if (oomProcs[oomIndex] == null) {
9290 oomProcs[oomIndex] = new ArrayList<MemItem>();
9291 }
9292 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009293 break;
9294 }
9295 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009296 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009297 }
9298 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009299
9300 if (!isCheckinRequest && procs.size() > 1) {
9301 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9302
9303 catMems.add(new MemItem("Native", nativePss));
9304 catMems.add(new MemItem("Dalvik", dalvikPss));
9305 catMems.add(new MemItem("Unknown", otherPss));
9306 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9307 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9308 }
9309
Dianne Hackbornb437e092011-08-05 17:50:29 -07009310 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9311 for (int j=0; j<oomPss.length; j++) {
9312 if (oomPss[j] != 0) {
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009313 MemItem item = new MemItem(oomLabel[j], oomPss[j]);
9314 item.subitems = oomProcs[j];
9315 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009316 }
9317 }
9318
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009319 pw.println();
9320 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009321 dumpMemItems(pw, " ", procMems, true);
9322 pw.println();
9323 pw.println("Total PSS by OOM adjustment:");
9324 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009325 pw.println();
9326 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009327 dumpMemItems(pw, " ", catMems, true);
9328 pw.println();
9329 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009331 }
9332
9333 /**
9334 * Searches array of arguments for the specified string
9335 * @param args array of argument strings
9336 * @param value value to search for
9337 * @return true if the value is contained in the array
9338 */
9339 private static boolean scanArgs(String[] args, String value) {
9340 if (args != null) {
9341 for (String arg : args) {
9342 if (value.equals(arg)) {
9343 return true;
9344 }
9345 }
9346 }
9347 return false;
9348 }
9349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009350 private final void killServicesLocked(ProcessRecord app,
9351 boolean allowRestart) {
9352 // Report disconnected services.
9353 if (false) {
9354 // XXX we are letting the client link to the service for
9355 // death notifications.
9356 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009357 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009358 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009359 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009360 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009361 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009362 = r.connections.values().iterator();
9363 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009364 ArrayList<ConnectionRecord> cl = jt.next();
9365 for (int i=0; i<cl.size(); i++) {
9366 ConnectionRecord c = cl.get(i);
9367 if (c.binding.client != app) {
9368 try {
9369 //c.conn.connected(r.className, null);
9370 } catch (Exception e) {
9371 // todo: this should be asynchronous!
9372 Slog.w(TAG, "Exception thrown disconnected servce "
9373 + r.shortName
9374 + " from app " + app.processName, e);
9375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009376 }
9377 }
9378 }
9379 }
9380 }
9381 }
9382 }
9383
9384 // Clean up any connections this application has to other services.
9385 if (app.connections.size() > 0) {
9386 Iterator<ConnectionRecord> it = app.connections.iterator();
9387 while (it.hasNext()) {
9388 ConnectionRecord r = it.next();
9389 removeConnectionLocked(r, app, null);
9390 }
9391 }
9392 app.connections.clear();
9393
9394 if (app.services.size() != 0) {
9395 // Any services running in the application need to be placed
9396 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009397 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009398 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009399 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009400 synchronized (sr.stats.getBatteryStats()) {
9401 sr.stats.stopLaunchedLocked();
9402 }
9403 sr.app = null;
9404 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009405 if (mStoppingServices.remove(sr)) {
9406 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9407 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009408
9409 boolean hasClients = sr.bindings.size() > 0;
9410 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009411 Iterator<IntentBindRecord> bindings
9412 = sr.bindings.values().iterator();
9413 while (bindings.hasNext()) {
9414 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009415 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009416 + ": shouldUnbind=" + b.hasBound);
9417 b.binder = null;
9418 b.requested = b.received = b.hasBound = false;
9419 }
9420 }
9421
Dianne Hackborn070783f2010-12-29 16:46:28 -08009422 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9423 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009424 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009425 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009426 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009427 sr.crashCount, sr.shortName, app.pid);
9428 bringDownServiceLocked(sr, true);
9429 } else if (!allowRestart) {
9430 bringDownServiceLocked(sr, true);
9431 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009432 boolean canceled = scheduleServiceRestartLocked(sr, true);
9433
9434 // Should the service remain running? Note that in the
9435 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009436 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009437 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9438 if (sr.pendingStarts.size() == 0) {
9439 sr.startRequested = false;
9440 if (!hasClients) {
9441 // Whoops, no reason to restart!
9442 bringDownServiceLocked(sr, true);
9443 }
9444 }
9445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009446 }
9447 }
9448
9449 if (!allowRestart) {
9450 app.services.clear();
9451 }
9452 }
9453
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009454 // Make sure we have no more records on the stopping list.
9455 int i = mStoppingServices.size();
9456 while (i > 0) {
9457 i--;
9458 ServiceRecord sr = mStoppingServices.get(i);
9459 if (sr.app == app) {
9460 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009461 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009462 }
9463 }
9464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009465 app.executingServices.clear();
9466 }
9467
9468 private final void removeDyingProviderLocked(ProcessRecord proc,
9469 ContentProviderRecord cpr) {
9470 synchronized (cpr) {
9471 cpr.launchingApp = null;
9472 cpr.notifyAll();
9473 }
9474
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009475 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009476 String names[] = cpr.info.authority.split(";");
9477 for (int j = 0; j < names.length; j++) {
9478 mProvidersByName.remove(names[j]);
9479 }
9480
9481 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9482 while (cit.hasNext()) {
9483 ProcessRecord capp = cit.next();
9484 if (!capp.persistent && capp.thread != null
9485 && capp.pid != 0
9486 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009487 Slog.i(TAG, "Kill " + capp.processName
9488 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009489 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -07009490 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009491 capp.processName, capp.setAdj, "dying provider "
9492 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009493 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494 }
9495 }
9496
9497 mLaunchingProviders.remove(cpr);
9498 }
9499
9500 /**
9501 * Main code for cleaning up a process when it has gone away. This is
9502 * called both as a result of the process dying, or directly when stopping
9503 * a process when running in single process mode.
9504 */
9505 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009506 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009507 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009508 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009509 }
9510
Dianne Hackborn36124872009-10-08 16:22:03 -07009511 mProcessesToGc.remove(app);
9512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009513 // Dismiss any open dialogs.
9514 if (app.crashDialog != null) {
9515 app.crashDialog.dismiss();
9516 app.crashDialog = null;
9517 }
9518 if (app.anrDialog != null) {
9519 app.anrDialog.dismiss();
9520 app.anrDialog = null;
9521 }
9522 if (app.waitDialog != null) {
9523 app.waitDialog.dismiss();
9524 app.waitDialog = null;
9525 }
9526
9527 app.crashing = false;
9528 app.notResponding = false;
9529
9530 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009531 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009532 app.thread = null;
9533 app.forcingToForeground = null;
9534 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009535 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009536 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009537 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009538
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009539 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009540
9541 boolean restart = false;
9542
9543 int NL = mLaunchingProviders.size();
9544
9545 // Remove published content providers.
9546 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009547 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009548 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009549 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009550 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009551 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009552
9553 // See if someone is waiting for this provider... in which
9554 // case we don't remove it, but just let it restart.
9555 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009556 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009557 for (; i<NL; i++) {
9558 if (mLaunchingProviders.get(i) == cpr) {
9559 restart = true;
9560 break;
9561 }
9562 }
9563 } else {
9564 i = NL;
9565 }
9566
9567 if (i >= NL) {
9568 removeDyingProviderLocked(app, cpr);
9569 NL = mLaunchingProviders.size();
9570 }
9571 }
9572 app.pubProviders.clear();
9573 }
9574
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009575 // Take care of any launching providers waiting for this process.
9576 if (checkAppInLaunchingProvidersLocked(app, false)) {
9577 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009578 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009580 // Unregister from connected content providers.
9581 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009582 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009583 while (it.hasNext()) {
9584 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9585 cpr.clients.remove(app);
9586 }
9587 app.conProviders.clear();
9588 }
9589
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009590 // At this point there may be remaining entries in mLaunchingProviders
9591 // where we were the only one waiting, so they are no longer of use.
9592 // Look for these and clean up if found.
9593 // XXX Commented out for now. Trying to figure out a way to reproduce
9594 // the actual situation to identify what is actually going on.
9595 if (false) {
9596 for (int i=0; i<NL; i++) {
9597 ContentProviderRecord cpr = (ContentProviderRecord)
9598 mLaunchingProviders.get(i);
9599 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9600 synchronized (cpr) {
9601 cpr.launchingApp = null;
9602 cpr.notifyAll();
9603 }
9604 }
9605 }
9606 }
9607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009608 skipCurrentReceiverLocked(app);
9609
9610 // Unregister any receivers.
9611 if (app.receivers.size() > 0) {
9612 Iterator<ReceiverList> it = app.receivers.iterator();
9613 while (it.hasNext()) {
9614 removeReceiverLocked(it.next());
9615 }
9616 app.receivers.clear();
9617 }
9618
Christopher Tate181fafa2009-05-14 11:12:14 -07009619 // If the app is undergoing backup, tell the backup manager about it
9620 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009621 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009622 try {
9623 IBackupManager bm = IBackupManager.Stub.asInterface(
9624 ServiceManager.getService(Context.BACKUP_SERVICE));
9625 bm.agentDisconnected(app.info.packageName);
9626 } catch (RemoteException e) {
9627 // can't happen; backup manager is local
9628 }
9629 }
9630
Jeff Sharkey287bd832011-05-28 19:36:26 -07009631 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009633 // If the caller is restarting this app, then leave it in its
9634 // current lists and let the caller take care of it.
9635 if (restarting) {
9636 return;
9637 }
9638
9639 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009640 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009641 "Removing non-persistent process during cleanup: " + app);
9642 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009643 if (mHeavyWeightProcess == app) {
9644 mHeavyWeightProcess = null;
9645 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9646 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009647 } else if (!app.removed) {
9648 // This app is persistent, so we need to keep its record around.
9649 // If it is not already on the pending app list, add it there
9650 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009651 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9652 mPersistentStartingProcesses.add(app);
9653 restart = true;
9654 }
9655 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009656 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9657 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009658 mProcessesOnHold.remove(app);
9659
The Android Open Source Project4df24232009-03-05 14:34:35 -08009660 if (app == mHomeProcess) {
9661 mHomeProcess = null;
9662 }
9663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009664 if (restart) {
9665 // We have components that still need to be running in the
9666 // process, so re-launch it.
9667 mProcessNames.put(app.processName, app.info.uid, app);
9668 startProcessLocked(app, "restart", app.processName);
9669 } else if (app.pid > 0 && app.pid != MY_PID) {
9670 // Goodbye!
9671 synchronized (mPidsSelfLocked) {
9672 mPidsSelfLocked.remove(app.pid);
9673 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9674 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009675 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009676 }
9677 }
9678
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009679 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9680 // Look through the content providers we are waiting to have launched,
9681 // and if any run in this process then either schedule a restart of
9682 // the process or kill the client waiting for it if this process has
9683 // gone bad.
9684 int NL = mLaunchingProviders.size();
9685 boolean restart = false;
9686 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009687 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009688 if (cpr.launchingApp == app) {
9689 if (!alwaysBad && !app.bad) {
9690 restart = true;
9691 } else {
9692 removeDyingProviderLocked(app, cpr);
9693 NL = mLaunchingProviders.size();
9694 }
9695 }
9696 }
9697 return restart;
9698 }
9699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009700 // =========================================================
9701 // SERVICES
9702 // =========================================================
9703
9704 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9705 ActivityManager.RunningServiceInfo info =
9706 new ActivityManager.RunningServiceInfo();
9707 info.service = r.name;
9708 if (r.app != null) {
9709 info.pid = r.app.pid;
9710 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009711 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009712 info.process = r.processName;
9713 info.foreground = r.isForeground;
9714 info.activeSince = r.createTime;
9715 info.started = r.startRequested;
9716 info.clientCount = r.connections.size();
9717 info.crashCount = r.crashCount;
9718 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009719 if (r.isForeground) {
9720 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9721 }
9722 if (r.startRequested) {
9723 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9724 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009725 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009726 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9727 }
9728 if (r.app != null && r.app.persistent) {
9729 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9730 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009731
9732 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9733 for (int i=0; i<connl.size(); i++) {
9734 ConnectionRecord conn = connl.get(i);
9735 if (conn.clientLabel != 0) {
9736 info.clientPackage = conn.binding.client.info.packageName;
9737 info.clientLabel = conn.clientLabel;
9738 return info;
9739 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009740 }
9741 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009742 return info;
9743 }
9744
9745 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9746 int flags) {
9747 synchronized (this) {
9748 ArrayList<ActivityManager.RunningServiceInfo> res
9749 = new ArrayList<ActivityManager.RunningServiceInfo>();
9750
9751 if (mServices.size() > 0) {
9752 Iterator<ServiceRecord> it = mServices.values().iterator();
9753 while (it.hasNext() && res.size() < maxNum) {
9754 res.add(makeRunningServiceInfoLocked(it.next()));
9755 }
9756 }
9757
9758 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9759 ServiceRecord r = mRestartingServices.get(i);
9760 ActivityManager.RunningServiceInfo info =
9761 makeRunningServiceInfoLocked(r);
9762 info.restarting = r.nextRestartTime;
9763 res.add(info);
9764 }
9765
9766 return res;
9767 }
9768 }
9769
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009770 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9771 synchronized (this) {
9772 ServiceRecord r = mServices.get(name);
9773 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009774 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9775 for (int i=0; i<conn.size(); i++) {
9776 if (conn.get(i).clientIntent != null) {
9777 return conn.get(i).clientIntent;
9778 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009779 }
9780 }
9781 }
9782 }
9783 return null;
9784 }
9785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009786 private final ServiceRecord findServiceLocked(ComponentName name,
9787 IBinder token) {
9788 ServiceRecord r = mServices.get(name);
9789 return r == token ? r : null;
9790 }
9791
9792 private final class ServiceLookupResult {
9793 final ServiceRecord record;
9794 final String permission;
9795
9796 ServiceLookupResult(ServiceRecord _record, String _permission) {
9797 record = _record;
9798 permission = _permission;
9799 }
9800 };
9801
9802 private ServiceLookupResult findServiceLocked(Intent service,
9803 String resolvedType) {
9804 ServiceRecord r = null;
9805 if (service.getComponent() != null) {
9806 r = mServices.get(service.getComponent());
9807 }
9808 if (r == null) {
9809 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9810 r = mServicesByIntent.get(filter);
9811 }
9812
9813 if (r == null) {
9814 try {
9815 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009816 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009817 service, resolvedType, 0);
9818 ServiceInfo sInfo =
9819 rInfo != null ? rInfo.serviceInfo : null;
9820 if (sInfo == null) {
9821 return null;
9822 }
9823
9824 ComponentName name = new ComponentName(
9825 sInfo.applicationInfo.packageName, sInfo.name);
9826 r = mServices.get(name);
9827 } catch (RemoteException ex) {
9828 // pm is in same process, this will never happen.
9829 }
9830 }
9831 if (r != null) {
9832 int callingPid = Binder.getCallingPid();
9833 int callingUid = Binder.getCallingUid();
9834 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009835 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009836 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009837 if (!r.exported) {
9838 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9839 + " from pid=" + callingPid
9840 + ", uid=" + callingUid
9841 + " that is not exported from uid " + r.appInfo.uid);
9842 return new ServiceLookupResult(null, "not exported from uid "
9843 + r.appInfo.uid);
9844 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009845 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009846 + " from pid=" + callingPid
9847 + ", uid=" + callingUid
9848 + " requires " + r.permission);
9849 return new ServiceLookupResult(null, r.permission);
9850 }
9851 return new ServiceLookupResult(r, null);
9852 }
9853 return null;
9854 }
9855
9856 private class ServiceRestarter implements Runnable {
9857 private ServiceRecord mService;
9858
9859 void setService(ServiceRecord service) {
9860 mService = service;
9861 }
9862
9863 public void run() {
9864 synchronized(ActivityManagerService.this) {
9865 performServiceRestartLocked(mService);
9866 }
9867 }
9868 }
9869
9870 private ServiceLookupResult retrieveServiceLocked(Intent service,
9871 String resolvedType, int callingPid, int callingUid) {
9872 ServiceRecord r = null;
9873 if (service.getComponent() != null) {
9874 r = mServices.get(service.getComponent());
9875 }
9876 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9877 r = mServicesByIntent.get(filter);
9878 if (r == null) {
9879 try {
9880 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009881 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009882 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009883 ServiceInfo sInfo =
9884 rInfo != null ? rInfo.serviceInfo : null;
9885 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009886 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009887 ": not found");
9888 return null;
9889 }
9890
9891 ComponentName name = new ComponentName(
9892 sInfo.applicationInfo.packageName, sInfo.name);
9893 r = mServices.get(name);
9894 if (r == null) {
9895 filter = new Intent.FilterComparison(service.cloneFilter());
9896 ServiceRestarter res = new ServiceRestarter();
9897 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9898 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9899 synchronized (stats) {
9900 ss = stats.getServiceStatsLocked(
9901 sInfo.applicationInfo.uid, sInfo.packageName,
9902 sInfo.name);
9903 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009904 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009905 res.setService(r);
9906 mServices.put(name, r);
9907 mServicesByIntent.put(filter, r);
9908
9909 // Make sure this component isn't in the pending list.
9910 int N = mPendingServices.size();
9911 for (int i=0; i<N; i++) {
9912 ServiceRecord pr = mPendingServices.get(i);
9913 if (pr.name.equals(name)) {
9914 mPendingServices.remove(i);
9915 i--;
9916 N--;
9917 }
9918 }
9919 }
9920 } catch (RemoteException ex) {
9921 // pm is in same process, this will never happen.
9922 }
9923 }
9924 if (r != null) {
9925 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009926 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009927 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009928 if (!r.exported) {
9929 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9930 + " from pid=" + callingPid
9931 + ", uid=" + callingUid
9932 + " that is not exported from uid " + r.appInfo.uid);
9933 return new ServiceLookupResult(null, "not exported from uid "
9934 + r.appInfo.uid);
9935 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009936 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009937 + " from pid=" + callingPid
9938 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009939 + " requires " + r.permission);
9940 return new ServiceLookupResult(null, r.permission);
9941 }
9942 return new ServiceLookupResult(r, null);
9943 }
9944 return null;
9945 }
9946
Dianne Hackborn287952c2010-09-22 22:34:31 -07009947 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9948 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9949 + why + " of " + r + " in app " + r.app);
9950 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9951 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009952 long now = SystemClock.uptimeMillis();
9953 if (r.executeNesting == 0 && r.app != null) {
9954 if (r.app.executingServices.size() == 0) {
9955 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9956 msg.obj = r.app;
9957 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9958 }
9959 r.app.executingServices.add(r);
9960 }
9961 r.executeNesting++;
9962 r.executingStart = now;
9963 }
9964
9965 private final void sendServiceArgsLocked(ServiceRecord r,
9966 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009967 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009968 if (N == 0) {
9969 return;
9970 }
9971
Dianne Hackborn39792d22010-08-19 18:01:52 -07009972 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009973 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009974 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009975 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9976 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009977 if (si.intent == null && N > 1) {
9978 // If somehow we got a dummy null intent in the middle,
9979 // then skip it. DO NOT skip a null intent when it is
9980 // the only one in the list -- this is to support the
9981 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009982 continue;
9983 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009984 si.deliveredTime = SystemClock.uptimeMillis();
9985 r.deliveredStarts.add(si);
9986 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009987 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009988 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009989 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009990 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009991 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009992 if (!oomAdjusted) {
9993 oomAdjusted = true;
9994 updateOomAdjLocked(r.app);
9995 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009996 int flags = 0;
9997 if (si.deliveryCount > 0) {
9998 flags |= Service.START_FLAG_RETRY;
9999 }
10000 if (si.doneExecutingCount > 0) {
10001 flags |= Service.START_FLAG_REDELIVERY;
10002 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010003 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010004 } catch (RemoteException e) {
10005 // Remote process gone... we'll let the normal cleanup take
10006 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010007 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010008 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010009 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010010 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010011 break;
10012 }
10013 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010014 }
10015
10016 private final boolean requestServiceBindingLocked(ServiceRecord r,
10017 IntentBindRecord i, boolean rebind) {
10018 if (r.app == null || r.app.thread == null) {
10019 // If service is not currently running, can't yet bind.
10020 return false;
10021 }
10022 if ((!i.requested || rebind) && i.apps.size() > 0) {
10023 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010024 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010025 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10026 if (!rebind) {
10027 i.requested = true;
10028 }
10029 i.hasBound = true;
10030 i.doRebind = false;
10031 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010032 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010033 return false;
10034 }
10035 }
10036 return true;
10037 }
10038
10039 private final void requestServiceBindingsLocked(ServiceRecord r) {
10040 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10041 while (bindings.hasNext()) {
10042 IntentBindRecord i = bindings.next();
10043 if (!requestServiceBindingLocked(r, i, false)) {
10044 break;
10045 }
10046 }
10047 }
10048
10049 private final void realStartServiceLocked(ServiceRecord r,
10050 ProcessRecord app) throws RemoteException {
10051 if (app.thread == null) {
10052 throw new RemoteException();
10053 }
10054
10055 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010056 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010057
10058 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010059 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010060 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010061
10062 boolean created = false;
10063 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010064 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010065 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010066 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010067 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010068 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010069 synchronized (r.stats.getBatteryStats()) {
10070 r.stats.startLaunchedLocked();
10071 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010072 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010073 app.thread.scheduleCreateService(r, r.serviceInfo,
10074 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010075 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010076 created = true;
10077 } finally {
10078 if (!created) {
10079 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010080 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010081 }
10082 }
10083
10084 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010085
10086 // If the service is in the started state, and there are no
10087 // pending arguments, then fake up one so its onStartCommand() will
10088 // be called.
10089 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010090 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10091 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010092 }
10093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010094 sendServiceArgsLocked(r, true);
10095 }
10096
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010097 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10098 boolean allowCancel) {
10099 boolean canceled = false;
10100
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010101 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010102 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010103 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010104
Dianne Hackborn070783f2010-12-29 16:46:28 -080010105 if ((r.serviceInfo.applicationInfo.flags
10106 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10107 minDuration /= 4;
10108 }
10109
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010110 // Any delivered but not yet finished starts should be put back
10111 // on the pending list.
10112 final int N = r.deliveredStarts.size();
10113 if (N > 0) {
10114 for (int i=N-1; i>=0; i--) {
10115 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010116 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010117 if (si.intent == null) {
10118 // We'll generate this again if needed.
10119 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10120 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10121 r.pendingStarts.add(0, si);
10122 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10123 dur *= 2;
10124 if (minDuration < dur) minDuration = dur;
10125 if (resetTime < dur) resetTime = dur;
10126 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010127 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010128 + r.name);
10129 canceled = true;
10130 }
10131 }
10132 r.deliveredStarts.clear();
10133 }
10134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010135 r.totalRestartCount++;
10136 if (r.restartDelay == 0) {
10137 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010138 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010139 } else {
10140 // If it has been a "reasonably long time" since the service
10141 // was started, then reset our restart duration back to
10142 // the beginning, so we don't infinitely increase the duration
10143 // on a service that just occasionally gets killed (which is
10144 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010145 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010146 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010147 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010148 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010149 if ((r.serviceInfo.applicationInfo.flags
10150 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10151 // Services in peristent processes will restart much more
10152 // quickly, since they are pretty important. (Think SystemUI).
10153 r.restartDelay += minDuration/2;
10154 } else {
10155 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10156 if (r.restartDelay < minDuration) {
10157 r.restartDelay = minDuration;
10158 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010159 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010160 }
10161 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010162
10163 r.nextRestartTime = now + r.restartDelay;
10164
10165 // Make sure that we don't end up restarting a bunch of services
10166 // all at the same time.
10167 boolean repeat;
10168 do {
10169 repeat = false;
10170 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10171 ServiceRecord r2 = mRestartingServices.get(i);
10172 if (r2 != r && r.nextRestartTime
10173 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10174 && r.nextRestartTime
10175 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10176 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10177 r.restartDelay = r.nextRestartTime - now;
10178 repeat = true;
10179 break;
10180 }
10181 }
10182 } while (repeat);
10183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010184 if (!mRestartingServices.contains(r)) {
10185 mRestartingServices.add(r);
10186 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010187
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010188 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010190 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010191 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010192 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010193 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010194 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010195 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010196 r.shortName, r.restartDelay);
10197
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010198 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010199 }
10200
10201 final void performServiceRestartLocked(ServiceRecord r) {
10202 if (!mRestartingServices.contains(r)) {
10203 return;
10204 }
10205 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10206 }
10207
10208 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10209 if (r.restartDelay == 0) {
10210 return false;
10211 }
10212 r.resetRestartCounter();
10213 mRestartingServices.remove(r);
10214 mHandler.removeCallbacks(r.restarter);
10215 return true;
10216 }
10217
10218 private final boolean bringUpServiceLocked(ServiceRecord r,
10219 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010220 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010221 //r.dump(" ");
10222
Dianne Hackborn36124872009-10-08 16:22:03 -070010223 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010224 sendServiceArgsLocked(r, false);
10225 return true;
10226 }
10227
10228 if (!whileRestarting && r.restartDelay > 0) {
10229 // If waiting for a restart, then do nothing.
10230 return true;
10231 }
10232
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010233 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010234
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010235 // We are now bringing the service up, so no longer in the
10236 // restarting state.
10237 mRestartingServices.remove(r);
10238
Dianne Hackborne7f97212011-02-24 14:40:20 -080010239 // Service is now being launched, its package can't be stopped.
10240 try {
10241 AppGlobals.getPackageManager().setPackageStoppedState(
10242 r.packageName, false);
10243 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010244 } catch (IllegalArgumentException e) {
10245 Slog.w(TAG, "Failed trying to unstop package "
10246 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010247 }
10248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010249 final String appName = r.processName;
10250 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10251 if (app != null && app.thread != null) {
10252 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010253 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010254 realStartServiceLocked(r, app);
10255 return true;
10256 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010257 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010258 }
10259
10260 // If a dead object exception was thrown -- fall through to
10261 // restart the application.
10262 }
10263
Dianne Hackborn36124872009-10-08 16:22:03 -070010264 // Not running -- get it started, and enqueue this service record
10265 // to be executed when the app comes up.
10266 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10267 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010268 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010269 + r.appInfo.packageName + "/"
10270 + r.appInfo.uid + " for service "
10271 + r.intent.getIntent() + ": process is bad");
10272 bringDownServiceLocked(r, true);
10273 return false;
10274 }
10275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010276 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010277 mPendingServices.add(r);
10278 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010280 return true;
10281 }
10282
10283 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010284 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010285 //r.dump(" ");
10286
10287 // Does it still need to run?
10288 if (!force && r.startRequested) {
10289 return;
10290 }
10291 if (r.connections.size() > 0) {
10292 if (!force) {
10293 // XXX should probably keep a count of the number of auto-create
10294 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010295 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010296 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010297 ArrayList<ConnectionRecord> cr = it.next();
10298 for (int i=0; i<cr.size(); i++) {
10299 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10300 return;
10301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010302 }
10303 }
10304 }
10305
10306 // Report to all of the connections that the service is no longer
10307 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010308 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010309 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010310 ArrayList<ConnectionRecord> c = it.next();
10311 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010312 ConnectionRecord cr = c.get(i);
10313 // There is still a connection to the service that is
10314 // being brought down. Mark it as dead.
10315 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010316 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010317 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010318 } catch (Exception e) {
10319 Slog.w(TAG, "Failure disconnecting service " + r.name +
10320 " to connection " + c.get(i).conn.asBinder() +
10321 " (in " + c.get(i).binding.client.processName + ")", e);
10322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010323 }
10324 }
10325 }
10326
10327 // Tell the service that it has been unbound.
10328 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10329 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10330 while (it.hasNext()) {
10331 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010332 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010333 + ": hasBound=" + ibr.hasBound);
10334 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10335 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010336 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010337 updateOomAdjLocked(r.app);
10338 ibr.hasBound = false;
10339 r.app.thread.scheduleUnbindService(r,
10340 ibr.intent.getIntent());
10341 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010342 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010343 + r.shortName, e);
10344 serviceDoneExecutingLocked(r, true);
10345 }
10346 }
10347 }
10348 }
10349
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010350 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010351 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010352 System.identityHashCode(r), r.shortName,
10353 (r.app != null) ? r.app.pid : -1);
10354
10355 mServices.remove(r.name);
10356 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010357 r.totalRestartCount = 0;
10358 unscheduleServiceRestartLocked(r);
10359
10360 // Also make sure it is not on the pending list.
10361 int N = mPendingServices.size();
10362 for (int i=0; i<N; i++) {
10363 if (mPendingServices.get(i) == r) {
10364 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010365 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010366 i--;
10367 N--;
10368 }
10369 }
10370
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010371 r.cancelNotification();
10372 r.isForeground = false;
10373 r.foregroundId = 0;
10374 r.foregroundNoti = null;
10375
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010376 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010377 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010378 r.pendingStarts.clear();
10379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010380 if (r.app != null) {
10381 synchronized (r.stats.getBatteryStats()) {
10382 r.stats.stopLaunchedLocked();
10383 }
10384 r.app.services.remove(r);
10385 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010386 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010387 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010388 mStoppingServices.add(r);
10389 updateOomAdjLocked(r.app);
10390 r.app.thread.scheduleStopService(r);
10391 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010392 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010393 + r.shortName, e);
10394 serviceDoneExecutingLocked(r, true);
10395 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010396 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010397 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010398 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010399 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010400 }
10401 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010402 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010403 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010404 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010405
10406 if (r.bindings.size() > 0) {
10407 r.bindings.clear();
10408 }
10409
10410 if (r.restarter instanceof ServiceRestarter) {
10411 ((ServiceRestarter)r.restarter).setService(null);
10412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010413 }
10414
10415 ComponentName startServiceLocked(IApplicationThread caller,
10416 Intent service, String resolvedType,
10417 int callingPid, int callingUid) {
10418 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010419 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010420 + " type=" + resolvedType + " args=" + service.getExtras());
10421
10422 if (caller != null) {
10423 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10424 if (callerApp == null) {
10425 throw new SecurityException(
10426 "Unable to find app for caller " + caller
10427 + " (pid=" + Binder.getCallingPid()
10428 + ") when starting service " + service);
10429 }
10430 }
10431
10432 ServiceLookupResult res =
10433 retrieveServiceLocked(service, resolvedType,
10434 callingPid, callingUid);
10435 if (res == null) {
10436 return null;
10437 }
10438 if (res.record == null) {
10439 return new ComponentName("!", res.permission != null
10440 ? res.permission : "private to package");
10441 }
10442 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010443 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10444 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010445 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010446 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010447 }
10448 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010449 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010450 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010451 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010452 r.lastActivity = SystemClock.uptimeMillis();
10453 synchronized (r.stats.getBatteryStats()) {
10454 r.stats.startRunningLocked();
10455 }
10456 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10457 return new ComponentName("!", "Service process is bad");
10458 }
10459 return r.name;
10460 }
10461 }
10462
10463 public ComponentName startService(IApplicationThread caller, Intent service,
10464 String resolvedType) {
10465 // Refuse possible leaked file descriptors
10466 if (service != null && service.hasFileDescriptors() == true) {
10467 throw new IllegalArgumentException("File descriptors passed in Intent");
10468 }
10469
10470 synchronized(this) {
10471 final int callingPid = Binder.getCallingPid();
10472 final int callingUid = Binder.getCallingUid();
10473 final long origId = Binder.clearCallingIdentity();
10474 ComponentName res = startServiceLocked(caller, service,
10475 resolvedType, callingPid, callingUid);
10476 Binder.restoreCallingIdentity(origId);
10477 return res;
10478 }
10479 }
10480
10481 ComponentName startServiceInPackage(int uid,
10482 Intent service, String resolvedType) {
10483 synchronized(this) {
10484 final long origId = Binder.clearCallingIdentity();
10485 ComponentName res = startServiceLocked(null, service,
10486 resolvedType, -1, uid);
10487 Binder.restoreCallingIdentity(origId);
10488 return res;
10489 }
10490 }
10491
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010492 private void stopServiceLocked(ServiceRecord service) {
10493 synchronized (service.stats.getBatteryStats()) {
10494 service.stats.stopRunningLocked();
10495 }
10496 service.startRequested = false;
10497 service.callStart = false;
10498 bringDownServiceLocked(service, false);
10499 }
10500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010501 public int stopService(IApplicationThread caller, Intent service,
10502 String resolvedType) {
10503 // Refuse possible leaked file descriptors
10504 if (service != null && service.hasFileDescriptors() == true) {
10505 throw new IllegalArgumentException("File descriptors passed in Intent");
10506 }
10507
10508 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010509 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010510 + " type=" + resolvedType);
10511
10512 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10513 if (caller != null && callerApp == null) {
10514 throw new SecurityException(
10515 "Unable to find app for caller " + caller
10516 + " (pid=" + Binder.getCallingPid()
10517 + ") when stopping service " + service);
10518 }
10519
10520 // If this service is active, make sure it is stopped.
10521 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10522 if (r != null) {
10523 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010524 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010525 try {
10526 stopServiceLocked(r.record);
10527 } finally {
10528 Binder.restoreCallingIdentity(origId);
10529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010530 return 1;
10531 }
10532 return -1;
10533 }
10534 }
10535
10536 return 0;
10537 }
10538
10539 public IBinder peekService(Intent service, String resolvedType) {
10540 // Refuse possible leaked file descriptors
10541 if (service != null && service.hasFileDescriptors() == true) {
10542 throw new IllegalArgumentException("File descriptors passed in Intent");
10543 }
10544
10545 IBinder ret = null;
10546
10547 synchronized(this) {
10548 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10549
10550 if (r != null) {
10551 // r.record is null if findServiceLocked() failed the caller permission check
10552 if (r.record == null) {
10553 throw new SecurityException(
10554 "Permission Denial: Accessing service " + r.record.name
10555 + " from pid=" + Binder.getCallingPid()
10556 + ", uid=" + Binder.getCallingUid()
10557 + " requires " + r.permission);
10558 }
10559 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10560 if (ib != null) {
10561 ret = ib.binder;
10562 }
10563 }
10564 }
10565
10566 return ret;
10567 }
10568
10569 public boolean stopServiceToken(ComponentName className, IBinder token,
10570 int startId) {
10571 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010572 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010573 + " " + token + " startId=" + startId);
10574 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010575 if (r != null) {
10576 if (startId >= 0) {
10577 // Asked to only stop if done with all work. Note that
10578 // to avoid leaks, we will take this as dropping all
10579 // start items up to and including this one.
10580 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10581 if (si != null) {
10582 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010583 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10584 cur.removeUriPermissionsLocked();
10585 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010586 break;
10587 }
10588 }
10589 }
10590
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010591 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010592 return false;
10593 }
10594
10595 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010596 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010597 + " is last, but have " + r.deliveredStarts.size()
10598 + " remaining args");
10599 }
10600 }
10601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010602 synchronized (r.stats.getBatteryStats()) {
10603 r.stats.stopRunningLocked();
10604 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010605 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010606 }
10607 final long origId = Binder.clearCallingIdentity();
10608 bringDownServiceLocked(r, false);
10609 Binder.restoreCallingIdentity(origId);
10610 return true;
10611 }
10612 }
10613 return false;
10614 }
10615
10616 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010617 int id, Notification notification, boolean removeNotification) {
10618 final long origId = Binder.clearCallingIdentity();
10619 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010620 synchronized(this) {
10621 ServiceRecord r = findServiceLocked(className, token);
10622 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010623 if (id != 0) {
10624 if (notification == null) {
10625 throw new IllegalArgumentException("null notification");
10626 }
10627 if (r.foregroundId != id) {
10628 r.cancelNotification();
10629 r.foregroundId = id;
10630 }
10631 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10632 r.foregroundNoti = notification;
10633 r.isForeground = true;
10634 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010635 if (r.app != null) {
10636 updateServiceForegroundLocked(r.app, true);
10637 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010638 } else {
10639 if (r.isForeground) {
10640 r.isForeground = false;
10641 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010642 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010643 updateServiceForegroundLocked(r.app, true);
10644 }
10645 }
10646 if (removeNotification) {
10647 r.cancelNotification();
10648 r.foregroundId = 0;
10649 r.foregroundNoti = null;
10650 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010651 }
10652 }
10653 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010654 } finally {
10655 Binder.restoreCallingIdentity(origId);
10656 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010657 }
10658
10659 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10660 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010661 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010662 if (sr.isForeground) {
10663 anyForeground = true;
10664 break;
10665 }
10666 }
10667 if (anyForeground != proc.foregroundServices) {
10668 proc.foregroundServices = anyForeground;
10669 if (oomAdj) {
10670 updateOomAdjLocked();
10671 }
10672 }
10673 }
10674
10675 public int bindService(IApplicationThread caller, IBinder token,
10676 Intent service, String resolvedType,
10677 IServiceConnection connection, int flags) {
10678 // Refuse possible leaked file descriptors
10679 if (service != null && service.hasFileDescriptors() == true) {
10680 throw new IllegalArgumentException("File descriptors passed in Intent");
10681 }
10682
10683 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010684 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010685 + " type=" + resolvedType + " conn=" + connection.asBinder()
10686 + " flags=0x" + Integer.toHexString(flags));
10687 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10688 if (callerApp == null) {
10689 throw new SecurityException(
10690 "Unable to find app for caller " + caller
10691 + " (pid=" + Binder.getCallingPid()
10692 + ") when binding service " + service);
10693 }
10694
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010695 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010696 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010697 activity = mMainStack.isInStackLocked(token);
10698 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010699 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010700 return 0;
10701 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010702 }
10703
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010704 int clientLabel = 0;
10705 PendingIntent clientIntent = null;
10706
10707 if (callerApp.info.uid == Process.SYSTEM_UID) {
10708 // Hacky kind of thing -- allow system stuff to tell us
10709 // what they are, so we can report this elsewhere for
10710 // others to know why certain services are running.
10711 try {
10712 clientIntent = (PendingIntent)service.getParcelableExtra(
10713 Intent.EXTRA_CLIENT_INTENT);
10714 } catch (RuntimeException e) {
10715 }
10716 if (clientIntent != null) {
10717 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10718 if (clientLabel != 0) {
10719 // There are no useful extras in the intent, trash them.
10720 // System code calling with this stuff just needs to know
10721 // this will happen.
10722 service = service.cloneFilter();
10723 }
10724 }
10725 }
10726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010727 ServiceLookupResult res =
10728 retrieveServiceLocked(service, resolvedType,
10729 Binder.getCallingPid(), Binder.getCallingUid());
10730 if (res == null) {
10731 return 0;
10732 }
10733 if (res.record == null) {
10734 return -1;
10735 }
10736 ServiceRecord s = res.record;
10737
10738 final long origId = Binder.clearCallingIdentity();
10739
10740 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010741 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010742 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010743 }
10744
10745 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10746 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010747 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010748
10749 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010750 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10751 if (clist == null) {
10752 clist = new ArrayList<ConnectionRecord>();
10753 s.connections.put(binder, clist);
10754 }
10755 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010756 b.connections.add(c);
10757 if (activity != null) {
10758 if (activity.connections == null) {
10759 activity.connections = new HashSet<ConnectionRecord>();
10760 }
10761 activity.connections.add(c);
10762 }
10763 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010764 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10765 b.client.hasAboveClient = true;
10766 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010767 clist = mServiceConnections.get(binder);
10768 if (clist == null) {
10769 clist = new ArrayList<ConnectionRecord>();
10770 mServiceConnections.put(binder, clist);
10771 }
10772 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010773
10774 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10775 s.lastActivity = SystemClock.uptimeMillis();
10776 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10777 return 0;
10778 }
10779 }
10780
10781 if (s.app != null) {
10782 // This could have made the service more important.
10783 updateOomAdjLocked(s.app);
10784 }
10785
Joe Onorato8a9b2202010-02-26 18:56:32 -080010786 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010787 + ": received=" + b.intent.received
10788 + " apps=" + b.intent.apps.size()
10789 + " doRebind=" + b.intent.doRebind);
10790
10791 if (s.app != null && b.intent.received) {
10792 // Service is already running, so we can immediately
10793 // publish the connection.
10794 try {
10795 c.conn.connected(s.name, b.intent.binder);
10796 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010797 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010798 + " to connection " + c.conn.asBinder()
10799 + " (in " + c.binding.client.processName + ")", e);
10800 }
10801
10802 // If this is the first app connected back to this binding,
10803 // and the service had previously asked to be told when
10804 // rebound, then do so.
10805 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10806 requestServiceBindingLocked(s, b.intent, true);
10807 }
10808 } else if (!b.intent.requested) {
10809 requestServiceBindingLocked(s, b.intent, false);
10810 }
10811
10812 Binder.restoreCallingIdentity(origId);
10813 }
10814
10815 return 1;
10816 }
10817
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010818 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010819 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010820 IBinder binder = c.conn.asBinder();
10821 AppBindRecord b = c.binding;
10822 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010823 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10824 if (clist != null) {
10825 clist.remove(c);
10826 if (clist.size() == 0) {
10827 s.connections.remove(binder);
10828 }
10829 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010830 b.connections.remove(c);
10831 if (c.activity != null && c.activity != skipAct) {
10832 if (c.activity.connections != null) {
10833 c.activity.connections.remove(c);
10834 }
10835 }
10836 if (b.client != skipApp) {
10837 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010838 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10839 b.client.updateHasAboveClientLocked();
10840 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010841 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010842 clist = mServiceConnections.get(binder);
10843 if (clist != null) {
10844 clist.remove(c);
10845 if (clist.size() == 0) {
10846 mServiceConnections.remove(binder);
10847 }
10848 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010849
10850 if (b.connections.size() == 0) {
10851 b.intent.apps.remove(b.client);
10852 }
10853
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010854 if (!c.serviceDead) {
10855 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10856 + ": shouldUnbind=" + b.intent.hasBound);
10857 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10858 && b.intent.hasBound) {
10859 try {
10860 bumpServiceExecutingLocked(s, "unbind");
10861 updateOomAdjLocked(s.app);
10862 b.intent.hasBound = false;
10863 // Assume the client doesn't want to know about a rebind;
10864 // we will deal with that later if it asks for one.
10865 b.intent.doRebind = false;
10866 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10867 } catch (Exception e) {
10868 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10869 serviceDoneExecutingLocked(s, true);
10870 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010871 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010872
10873 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10874 bringDownServiceLocked(s, false);
10875 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010876 }
10877 }
10878
10879 public boolean unbindService(IServiceConnection connection) {
10880 synchronized (this) {
10881 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010882 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010883 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10884 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010885 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010886 + connection.asBinder());
10887 return false;
10888 }
10889
10890 final long origId = Binder.clearCallingIdentity();
10891
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010892 while (clist.size() > 0) {
10893 ConnectionRecord r = clist.get(0);
10894 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010895
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010896 if (r.binding.service.app != null) {
10897 // This could have made the service less important.
10898 updateOomAdjLocked(r.binding.service.app);
10899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010900 }
10901
10902 Binder.restoreCallingIdentity(origId);
10903 }
10904
10905 return true;
10906 }
10907
10908 public void publishService(IBinder token, Intent intent, IBinder service) {
10909 // Refuse possible leaked file descriptors
10910 if (intent != null && intent.hasFileDescriptors() == true) {
10911 throw new IllegalArgumentException("File descriptors passed in Intent");
10912 }
10913
10914 synchronized(this) {
10915 if (!(token instanceof ServiceRecord)) {
10916 throw new IllegalArgumentException("Invalid service token");
10917 }
10918 ServiceRecord r = (ServiceRecord)token;
10919
10920 final long origId = Binder.clearCallingIdentity();
10921
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010922 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010923 + " " + intent + ": " + service);
10924 if (r != null) {
10925 Intent.FilterComparison filter
10926 = new Intent.FilterComparison(intent);
10927 IntentBindRecord b = r.bindings.get(filter);
10928 if (b != null && !b.received) {
10929 b.binder = service;
10930 b.requested = true;
10931 b.received = true;
10932 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010933 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010934 = r.connections.values().iterator();
10935 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010936 ArrayList<ConnectionRecord> clist = it.next();
10937 for (int i=0; i<clist.size(); i++) {
10938 ConnectionRecord c = clist.get(i);
10939 if (!filter.equals(c.binding.intent.intent)) {
10940 if (DEBUG_SERVICE) Slog.v(
10941 TAG, "Not publishing to: " + c);
10942 if (DEBUG_SERVICE) Slog.v(
10943 TAG, "Bound intent: " + c.binding.intent.intent);
10944 if (DEBUG_SERVICE) Slog.v(
10945 TAG, "Published intent: " + intent);
10946 continue;
10947 }
10948 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10949 try {
10950 c.conn.connected(r.name, service);
10951 } catch (Exception e) {
10952 Slog.w(TAG, "Failure sending service " + r.name +
10953 " to connection " + c.conn.asBinder() +
10954 " (in " + c.binding.client.processName + ")", e);
10955 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010956 }
10957 }
10958 }
10959 }
10960
10961 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10962
10963 Binder.restoreCallingIdentity(origId);
10964 }
10965 }
10966 }
10967
10968 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10969 // Refuse possible leaked file descriptors
10970 if (intent != null && intent.hasFileDescriptors() == true) {
10971 throw new IllegalArgumentException("File descriptors passed in Intent");
10972 }
10973
10974 synchronized(this) {
10975 if (!(token instanceof ServiceRecord)) {
10976 throw new IllegalArgumentException("Invalid service token");
10977 }
10978 ServiceRecord r = (ServiceRecord)token;
10979
10980 final long origId = Binder.clearCallingIdentity();
10981
10982 if (r != null) {
10983 Intent.FilterComparison filter
10984 = new Intent.FilterComparison(intent);
10985 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010986 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010987 + " at " + b + ": apps="
10988 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020010989
10990 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010991 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020010992 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010993 // Applications have already bound since the last
10994 // unbind, so just rebind right here.
10995 requestServiceBindingLocked(r, b, true);
10996 } else {
10997 // Note to tell the service the next time there is
10998 // a new client.
10999 b.doRebind = true;
11000 }
11001 }
11002
Per Edelberg78f9fff2010-08-30 20:01:35 +020011003 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011004
11005 Binder.restoreCallingIdentity(origId);
11006 }
11007 }
11008 }
11009
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011010 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011011 synchronized(this) {
11012 if (!(token instanceof ServiceRecord)) {
11013 throw new IllegalArgumentException("Invalid service token");
11014 }
11015 ServiceRecord r = (ServiceRecord)token;
11016 boolean inStopping = mStoppingServices.contains(token);
11017 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011018 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011019 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011020 + " with incorrect token: given " + token
11021 + ", expected " + r);
11022 return;
11023 }
11024
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011025 if (type == 1) {
11026 // This is a call from a service start... take care of
11027 // book-keeping.
11028 r.callStart = true;
11029 switch (res) {
11030 case Service.START_STICKY_COMPATIBILITY:
11031 case Service.START_STICKY: {
11032 // We are done with the associated start arguments.
11033 r.findDeliveredStart(startId, true);
11034 // Don't stop if killed.
11035 r.stopIfKilled = false;
11036 break;
11037 }
11038 case Service.START_NOT_STICKY: {
11039 // We are done with the associated start arguments.
11040 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011041 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011042 // There is no more work, and this service
11043 // doesn't want to hang around if killed.
11044 r.stopIfKilled = true;
11045 }
11046 break;
11047 }
11048 case Service.START_REDELIVER_INTENT: {
11049 // We'll keep this item until they explicitly
11050 // call stop for it, but keep track of the fact
11051 // that it was delivered.
11052 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11053 if (si != null) {
11054 si.deliveryCount = 0;
11055 si.doneExecutingCount++;
11056 // Don't stop if killed.
11057 r.stopIfKilled = true;
11058 }
11059 break;
11060 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011061 case Service.START_TASK_REMOVED_COMPLETE: {
11062 // Special processing for onTaskRemoved(). Don't
11063 // impact normal onStartCommand() processing.
11064 r.findDeliveredStart(startId, true);
11065 break;
11066 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011067 default:
11068 throw new IllegalArgumentException(
11069 "Unknown service start result: " + res);
11070 }
11071 if (res == Service.START_STICKY_COMPATIBILITY) {
11072 r.callStart = false;
11073 }
11074 }
11075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011076 final long origId = Binder.clearCallingIdentity();
11077 serviceDoneExecutingLocked(r, inStopping);
11078 Binder.restoreCallingIdentity(origId);
11079 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011080 Slog.w(TAG, "Done executing unknown service from pid "
11081 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011082 }
11083 }
11084 }
11085
11086 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011087 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11088 + ": nesting=" + r.executeNesting
11089 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011090 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011091 r.executeNesting--;
11092 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011093 if (DEBUG_SERVICE) Slog.v(TAG,
11094 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011095 r.app.executingServices.remove(r);
11096 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011097 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11098 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011099 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11100 }
11101 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011102 if (DEBUG_SERVICE) Slog.v(TAG,
11103 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011104 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011105 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011106 }
11107 updateOomAdjLocked(r.app);
11108 }
11109 }
11110
11111 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011112 String anrMessage = null;
11113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011114 synchronized(this) {
11115 if (proc.executingServices.size() == 0 || proc.thread == null) {
11116 return;
11117 }
11118 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11119 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11120 ServiceRecord timeout = null;
11121 long nextTime = 0;
11122 while (it.hasNext()) {
11123 ServiceRecord sr = it.next();
11124 if (sr.executingStart < maxTime) {
11125 timeout = sr;
11126 break;
11127 }
11128 if (sr.executingStart > nextTime) {
11129 nextTime = sr.executingStart;
11130 }
11131 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011132 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011133 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011134 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011135 } else {
11136 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11137 msg.obj = proc;
11138 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11139 }
11140 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011141
11142 if (anrMessage != null) {
11143 appNotResponding(proc, null, null, anrMessage);
11144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011145 }
11146
11147 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011148 // BACKUP AND RESTORE
11149 // =========================================================
11150
11151 // Cause the target app to be launched if necessary and its backup agent
11152 // instantiated. The backup agent will invoke backupAgentCreated() on the
11153 // activity manager to announce its creation.
11154 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011155 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011156 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11157
11158 synchronized(this) {
11159 // !!! TODO: currently no check here that we're already bound
11160 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11161 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11162 synchronized (stats) {
11163 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11164 }
11165
Dianne Hackborne7f97212011-02-24 14:40:20 -080011166 // Backup agent is now in use, its package can't be stopped.
11167 try {
11168 AppGlobals.getPackageManager().setPackageStoppedState(
11169 app.packageName, false);
11170 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011171 } catch (IllegalArgumentException e) {
11172 Slog.w(TAG, "Failed trying to unstop package "
11173 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011174 }
11175
Christopher Tate181fafa2009-05-14 11:12:14 -070011176 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011177 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11178 ? new ComponentName(app.packageName, app.backupAgentName)
11179 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011180 // startProcessLocked() returns existing proc's record if it's already running
11181 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011182 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011183 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011184 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011185 return false;
11186 }
11187
11188 r.app = proc;
11189 mBackupTarget = r;
11190 mBackupAppName = app.packageName;
11191
Christopher Tate6fa95972009-06-05 18:43:55 -070011192 // Try not to kill the process during backup
11193 updateOomAdjLocked(proc);
11194
Christopher Tate181fafa2009-05-14 11:12:14 -070011195 // If the process is already attached, schedule the creation of the backup agent now.
11196 // If it is not yet live, this will be done when it attaches to the framework.
11197 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011198 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011199 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011200 proc.thread.scheduleCreateBackupAgent(app,
11201 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011202 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011203 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011204 }
11205 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011206 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011207 }
11208 // Invariants: at this point, the target app process exists and the application
11209 // is either already running or in the process of coming up. mBackupTarget and
11210 // mBackupAppName describe the app, so that when it binds back to the AM we
11211 // know that it's scheduled for a backup-agent operation.
11212 }
11213
11214 return true;
11215 }
11216
11217 // A backup agent has just come up
11218 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011219 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011220 + " = " + agent);
11221
11222 synchronized(this) {
11223 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011224 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011225 return;
11226 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011227 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011228
Dianne Hackborn06740692010-09-22 22:46:21 -070011229 long oldIdent = Binder.clearCallingIdentity();
11230 try {
11231 IBackupManager bm = IBackupManager.Stub.asInterface(
11232 ServiceManager.getService(Context.BACKUP_SERVICE));
11233 bm.agentConnected(agentPackageName, agent);
11234 } catch (RemoteException e) {
11235 // can't happen; the backup manager service is local
11236 } catch (Exception e) {
11237 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11238 e.printStackTrace();
11239 } finally {
11240 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011241 }
11242 }
11243
11244 // done with this agent
11245 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011246 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011247 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011248 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011249 return;
11250 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011251
11252 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011253 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011254 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011255 return;
11256 }
11257
Christopher Tate181fafa2009-05-14 11:12:14 -070011258 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011259 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011260 return;
11261 }
11262
Christopher Tate6fa95972009-06-05 18:43:55 -070011263 ProcessRecord proc = mBackupTarget.app;
11264 mBackupTarget = null;
11265 mBackupAppName = null;
11266
11267 // Not backing this app up any more; reset its OOM adjustment
11268 updateOomAdjLocked(proc);
11269
Christopher Tatec7b31e32009-06-10 15:49:30 -070011270 // If the app crashed during backup, 'thread' will be null here
11271 if (proc.thread != null) {
11272 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011273 proc.thread.scheduleDestroyBackupAgent(appInfo,
11274 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011275 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011276 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011277 e.printStackTrace();
11278 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011279 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011280 }
11281 }
11282 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011283 // BROADCASTS
11284 // =========================================================
11285
Josh Bartel7f208742010-02-25 11:01:44 -060011286 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011287 List cur) {
11288 final ContentResolver resolver = mContext.getContentResolver();
11289 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11290 if (list == null) {
11291 return cur;
11292 }
11293 int N = list.size();
11294 for (int i=0; i<N; i++) {
11295 Intent intent = list.get(i);
11296 if (filter.match(resolver, intent, true, TAG) >= 0) {
11297 if (cur == null) {
11298 cur = new ArrayList<Intent>();
11299 }
11300 cur.add(intent);
11301 }
11302 }
11303 return cur;
11304 }
11305
11306 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011307 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011308 + mBroadcastsScheduled);
11309
11310 if (mBroadcastsScheduled) {
11311 return;
11312 }
11313 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11314 mBroadcastsScheduled = true;
11315 }
11316
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011317 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011318 IIntentReceiver receiver, IntentFilter filter, String permission) {
11319 synchronized(this) {
11320 ProcessRecord callerApp = null;
11321 if (caller != null) {
11322 callerApp = getRecordForAppLocked(caller);
11323 if (callerApp == null) {
11324 throw new SecurityException(
11325 "Unable to find app for caller " + caller
11326 + " (pid=" + Binder.getCallingPid()
11327 + ") when registering receiver " + receiver);
11328 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011329 if (callerApp.info.uid != Process.SYSTEM_UID &&
11330 !callerApp.pkgList.contains(callerPackage)) {
11331 throw new SecurityException("Given caller package " + callerPackage
11332 + " is not running in process " + callerApp);
11333 }
11334 } else {
11335 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011336 }
11337
11338 List allSticky = null;
11339
11340 // Look for any matching sticky broadcasts...
11341 Iterator actions = filter.actionsIterator();
11342 if (actions != null) {
11343 while (actions.hasNext()) {
11344 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011345 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011346 }
11347 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011348 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011349 }
11350
11351 // The first sticky in the list is returned directly back to
11352 // the client.
11353 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11354
Joe Onorato8a9b2202010-02-26 18:56:32 -080011355 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011356 + ": " + sticky);
11357
11358 if (receiver == null) {
11359 return sticky;
11360 }
11361
11362 ReceiverList rl
11363 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11364 if (rl == null) {
11365 rl = new ReceiverList(this, callerApp,
11366 Binder.getCallingPid(),
11367 Binder.getCallingUid(), receiver);
11368 if (rl.app != null) {
11369 rl.app.receivers.add(rl);
11370 } else {
11371 try {
11372 receiver.asBinder().linkToDeath(rl, 0);
11373 } catch (RemoteException e) {
11374 return sticky;
11375 }
11376 rl.linkedToDeath = true;
11377 }
11378 mRegisteredReceivers.put(receiver.asBinder(), rl);
11379 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011380 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011381 rl.add(bf);
11382 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011383 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011384 }
11385 mReceiverResolver.addFilter(bf);
11386
11387 // Enqueue broadcasts for all existing stickies that match
11388 // this filter.
11389 if (allSticky != null) {
11390 ArrayList receivers = new ArrayList();
11391 receivers.add(bf);
11392
11393 int N = allSticky.size();
11394 for (int i=0; i<N; i++) {
11395 Intent intent = (Intent)allSticky.get(i);
11396 BroadcastRecord r = new BroadcastRecord(intent, null,
11397 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011398 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011399 if (mParallelBroadcasts.size() == 0) {
11400 scheduleBroadcastsLocked();
11401 }
11402 mParallelBroadcasts.add(r);
11403 }
11404 }
11405
11406 return sticky;
11407 }
11408 }
11409
11410 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011411 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011412
11413 boolean doNext = false;
11414
11415 synchronized(this) {
11416 ReceiverList rl
11417 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11418 if (rl != null) {
11419 if (rl.curBroadcast != null) {
11420 BroadcastRecord r = rl.curBroadcast;
11421 doNext = finishReceiverLocked(
11422 receiver.asBinder(), r.resultCode, r.resultData,
11423 r.resultExtras, r.resultAbort, true);
11424 }
11425
11426 if (rl.app != null) {
11427 rl.app.receivers.remove(rl);
11428 }
11429 removeReceiverLocked(rl);
11430 if (rl.linkedToDeath) {
11431 rl.linkedToDeath = false;
11432 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11433 }
11434 }
11435 }
11436
11437 if (!doNext) {
11438 return;
11439 }
11440
11441 final long origId = Binder.clearCallingIdentity();
11442 processNextBroadcast(false);
11443 trimApplications();
11444 Binder.restoreCallingIdentity(origId);
11445 }
11446
11447 void removeReceiverLocked(ReceiverList rl) {
11448 mRegisteredReceivers.remove(rl.receiver.asBinder());
11449 int N = rl.size();
11450 for (int i=0; i<N; i++) {
11451 mReceiverResolver.removeFilter(rl.get(i));
11452 }
11453 }
11454
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011455 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11456 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11457 ProcessRecord r = mLruProcesses.get(i);
11458 if (r.thread != null) {
11459 try {
11460 r.thread.dispatchPackageBroadcast(cmd, packages);
11461 } catch (RemoteException ex) {
11462 }
11463 }
11464 }
11465 }
11466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011467 private final int broadcastIntentLocked(ProcessRecord callerApp,
11468 String callerPackage, Intent intent, String resolvedType,
11469 IIntentReceiver resultTo, int resultCode, String resultData,
11470 Bundle map, String requiredPermission,
11471 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11472 intent = new Intent(intent);
11473
Dianne Hackborne7f97212011-02-24 14:40:20 -080011474 // By default broadcasts do not go to stopped apps.
11475 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11476
Joe Onorato8a9b2202010-02-26 18:56:32 -080011477 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011478 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11479 + " ordered=" + ordered);
11480 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011481 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011482 }
11483
11484 // Handle special intents: if this broadcast is from the package
11485 // manager about a package being removed, we need to remove all of
11486 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011487 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011488 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011489 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11490 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011491 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011492 || uidRemoved) {
11493 if (checkComponentPermission(
11494 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011495 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011496 == PackageManager.PERMISSION_GRANTED) {
11497 if (uidRemoved) {
11498 final Bundle intentExtras = intent.getExtras();
11499 final int uid = intentExtras != null
11500 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11501 if (uid >= 0) {
11502 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11503 synchronized (bs) {
11504 bs.removeUidStatsLocked(uid);
11505 }
11506 }
11507 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011508 // If resources are unvailble just force stop all
11509 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011510 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011511 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11512 if (list != null && (list.length > 0)) {
11513 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011514 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011515 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011516 sendPackageBroadcastLocked(
11517 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011518 }
11519 } else {
11520 Uri data = intent.getData();
11521 String ssp;
11522 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11523 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11524 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011525 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011526 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011527 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011528 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11529 new String[] {ssp});
11530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011531 }
11532 }
11533 }
11534 } else {
11535 String msg = "Permission Denial: " + intent.getAction()
11536 + " broadcast from " + callerPackage + " (pid=" + callingPid
11537 + ", uid=" + callingUid + ")"
11538 + " requires "
11539 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011540 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011541 throw new SecurityException(msg);
11542 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011543
11544 // Special case for adding a package: by default turn on compatibility
11545 // mode.
11546 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011547 Uri data = intent.getData();
11548 String ssp;
11549 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11550 mCompatModePackages.handlePackageAddedLocked(ssp,
11551 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011552 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011553 }
11554
11555 /*
11556 * If this is the time zone changed action, queue up a message that will reset the timezone
11557 * of all currently running processes. This message will get queued up before the broadcast
11558 * happens.
11559 */
11560 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11561 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11562 }
11563
Robert Greenwalt03595d02010-11-02 14:08:23 -070011564 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11565 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11566 }
11567
Robert Greenwalt434203a2010-10-11 16:00:27 -070011568 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11569 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11570 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11571 }
11572
Dianne Hackborn854060af2009-07-09 18:14:31 -070011573 /*
11574 * Prevent non-system code (defined here to be non-persistent
11575 * processes) from sending protected broadcasts.
11576 */
11577 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11578 || callingUid == Process.SHELL_UID || callingUid == 0) {
11579 // Always okay.
11580 } else if (callerApp == null || !callerApp.persistent) {
11581 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011582 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011583 intent.getAction())) {
11584 String msg = "Permission Denial: not allowed to send broadcast "
11585 + intent.getAction() + " from pid="
11586 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011587 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011588 throw new SecurityException(msg);
11589 }
11590 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011591 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011592 return BROADCAST_SUCCESS;
11593 }
11594 }
11595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011596 // Add to the sticky list if requested.
11597 if (sticky) {
11598 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11599 callingPid, callingUid)
11600 != PackageManager.PERMISSION_GRANTED) {
11601 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11602 + callingPid + ", uid=" + callingUid
11603 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011604 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011605 throw new SecurityException(msg);
11606 }
11607 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011608 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011609 + " and enforce permission " + requiredPermission);
11610 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11611 }
11612 if (intent.getComponent() != null) {
11613 throw new SecurityException(
11614 "Sticky broadcasts can't target a specific component");
11615 }
11616 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11617 if (list == null) {
11618 list = new ArrayList<Intent>();
11619 mStickyBroadcasts.put(intent.getAction(), list);
11620 }
11621 int N = list.size();
11622 int i;
11623 for (i=0; i<N; i++) {
11624 if (intent.filterEquals(list.get(i))) {
11625 // This sticky already exists, replace it.
11626 list.set(i, new Intent(intent));
11627 break;
11628 }
11629 }
11630 if (i >= N) {
11631 list.add(new Intent(intent));
11632 }
11633 }
11634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011635 // Figure out who all will receive this broadcast.
11636 List receivers = null;
11637 List<BroadcastFilter> registeredReceivers = null;
11638 try {
11639 if (intent.getComponent() != null) {
11640 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011641 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011642 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011643 if (ai != null) {
11644 receivers = new ArrayList();
11645 ResolveInfo ri = new ResolveInfo();
11646 ri.activityInfo = ai;
11647 receivers.add(ri);
11648 }
11649 } else {
11650 // Need to resolve the intent to interested receivers...
11651 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11652 == 0) {
11653 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011654 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011655 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011656 }
Mihai Preda074edef2009-05-18 17:13:31 +020011657 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011658 }
11659 } catch (RemoteException ex) {
11660 // pm is in same process, this will never happen.
11661 }
11662
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011663 final boolean replacePending =
11664 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11665
Joe Onorato8a9b2202010-02-26 18:56:32 -080011666 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011667 + " replacePending=" + replacePending);
11668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011669 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11670 if (!ordered && NR > 0) {
11671 // If we are not serializing this broadcast, then send the
11672 // registered receivers separately so they don't wait for the
11673 // components to be launched.
11674 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11675 callerPackage, callingPid, callingUid, requiredPermission,
11676 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011677 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011678 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011679 TAG, "Enqueueing parallel broadcast " + r
11680 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011681 boolean replaced = false;
11682 if (replacePending) {
11683 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11684 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011685 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011686 "***** DROPPING PARALLEL: " + intent);
11687 mParallelBroadcasts.set(i, r);
11688 replaced = true;
11689 break;
11690 }
11691 }
11692 }
11693 if (!replaced) {
11694 mParallelBroadcasts.add(r);
11695 scheduleBroadcastsLocked();
11696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011697 registeredReceivers = null;
11698 NR = 0;
11699 }
11700
11701 // Merge into one list.
11702 int ir = 0;
11703 if (receivers != null) {
11704 // A special case for PACKAGE_ADDED: do not allow the package
11705 // being added to see this broadcast. This prevents them from
11706 // using this as a back door to get run as soon as they are
11707 // installed. Maybe in the future we want to have a special install
11708 // broadcast or such for apps, but we'd like to deliberately make
11709 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011710 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011711 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11712 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11713 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011714 Uri data = intent.getData();
11715 if (data != null) {
11716 String pkgName = data.getSchemeSpecificPart();
11717 if (pkgName != null) {
11718 skipPackages = new String[] { pkgName };
11719 }
11720 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011721 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011722 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011723 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011724 if (skipPackages != null && (skipPackages.length > 0)) {
11725 for (String skipPackage : skipPackages) {
11726 if (skipPackage != null) {
11727 int NT = receivers.size();
11728 for (int it=0; it<NT; it++) {
11729 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11730 if (curt.activityInfo.packageName.equals(skipPackage)) {
11731 receivers.remove(it);
11732 it--;
11733 NT--;
11734 }
11735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011736 }
11737 }
11738 }
11739
11740 int NT = receivers != null ? receivers.size() : 0;
11741 int it = 0;
11742 ResolveInfo curt = null;
11743 BroadcastFilter curr = null;
11744 while (it < NT && ir < NR) {
11745 if (curt == null) {
11746 curt = (ResolveInfo)receivers.get(it);
11747 }
11748 if (curr == null) {
11749 curr = registeredReceivers.get(ir);
11750 }
11751 if (curr.getPriority() >= curt.priority) {
11752 // Insert this broadcast record into the final list.
11753 receivers.add(it, curr);
11754 ir++;
11755 curr = null;
11756 it++;
11757 NT++;
11758 } else {
11759 // Skip to the next ResolveInfo in the final list.
11760 it++;
11761 curt = null;
11762 }
11763 }
11764 }
11765 while (ir < NR) {
11766 if (receivers == null) {
11767 receivers = new ArrayList();
11768 }
11769 receivers.add(registeredReceivers.get(ir));
11770 ir++;
11771 }
11772
11773 if ((receivers != null && receivers.size() > 0)
11774 || resultTo != null) {
11775 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11776 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011777 receivers, resultTo, resultCode, resultData, map, ordered,
11778 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011779 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011780 TAG, "Enqueueing ordered broadcast " + r
11781 + ": prev had " + mOrderedBroadcasts.size());
11782 if (DEBUG_BROADCAST) {
11783 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011784 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011785 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011786 boolean replaced = false;
11787 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011788 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011789 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011790 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011791 "***** DROPPING ORDERED: " + intent);
11792 mOrderedBroadcasts.set(i, r);
11793 replaced = true;
11794 break;
11795 }
11796 }
11797 }
11798 if (!replaced) {
11799 mOrderedBroadcasts.add(r);
11800 scheduleBroadcastsLocked();
11801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011802 }
11803
11804 return BROADCAST_SUCCESS;
11805 }
11806
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011807 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011808 // Refuse possible leaked file descriptors
11809 if (intent != null && intent.hasFileDescriptors() == true) {
11810 throw new IllegalArgumentException("File descriptors passed in Intent");
11811 }
11812
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011813 int flags = intent.getFlags();
11814
11815 if (!mProcessesReady) {
11816 // if the caller really truly claims to know what they're doing, go
11817 // ahead and allow the broadcast without launching any receivers
11818 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11819 intent = new Intent(intent);
11820 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11821 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11822 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11823 + " before boot completion");
11824 throw new IllegalStateException("Cannot broadcast before boot completed");
11825 }
11826 }
11827
11828 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11829 throw new IllegalArgumentException(
11830 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11831 }
11832
11833 return intent;
11834 }
11835
11836 public final int broadcastIntent(IApplicationThread caller,
11837 Intent intent, String resolvedType, IIntentReceiver resultTo,
11838 int resultCode, String resultData, Bundle map,
11839 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011840 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011841 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011843 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11844 final int callingPid = Binder.getCallingPid();
11845 final int callingUid = Binder.getCallingUid();
11846 final long origId = Binder.clearCallingIdentity();
11847 int res = broadcastIntentLocked(callerApp,
11848 callerApp != null ? callerApp.info.packageName : null,
11849 intent, resolvedType, resultTo,
11850 resultCode, resultData, map, requiredPermission, serialized,
11851 sticky, callingPid, callingUid);
11852 Binder.restoreCallingIdentity(origId);
11853 return res;
11854 }
11855 }
11856
11857 int broadcastIntentInPackage(String packageName, int uid,
11858 Intent intent, String resolvedType, IIntentReceiver resultTo,
11859 int resultCode, String resultData, Bundle map,
11860 String requiredPermission, boolean serialized, boolean sticky) {
11861 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011862 intent = verifyBroadcastLocked(intent);
11863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011864 final long origId = Binder.clearCallingIdentity();
11865 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11866 resultTo, resultCode, resultData, map, requiredPermission,
11867 serialized, sticky, -1, uid);
11868 Binder.restoreCallingIdentity(origId);
11869 return res;
11870 }
11871 }
11872
11873 public final void unbroadcastIntent(IApplicationThread caller,
11874 Intent intent) {
11875 // Refuse possible leaked file descriptors
11876 if (intent != null && intent.hasFileDescriptors() == true) {
11877 throw new IllegalArgumentException("File descriptors passed in Intent");
11878 }
11879
11880 synchronized(this) {
11881 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11882 != PackageManager.PERMISSION_GRANTED) {
11883 String msg = "Permission Denial: unbroadcastIntent() from pid="
11884 + Binder.getCallingPid()
11885 + ", uid=" + Binder.getCallingUid()
11886 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011887 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011888 throw new SecurityException(msg);
11889 }
11890 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11891 if (list != null) {
11892 int N = list.size();
11893 int i;
11894 for (i=0; i<N; i++) {
11895 if (intent.filterEquals(list.get(i))) {
11896 list.remove(i);
11897 break;
11898 }
11899 }
11900 }
11901 }
11902 }
11903
11904 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11905 String resultData, Bundle resultExtras, boolean resultAbort,
11906 boolean explicit) {
11907 if (mOrderedBroadcasts.size() == 0) {
11908 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011909 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011910 }
11911 return false;
11912 }
11913 BroadcastRecord r = mOrderedBroadcasts.get(0);
11914 if (r.receiver == null) {
11915 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011916 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011917 }
11918 return false;
11919 }
11920 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011921 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011922 return false;
11923 }
11924 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011925 r.state = BroadcastRecord.IDLE;
11926 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011927 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011928 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011929 }
11930 }
11931 r.receiver = null;
11932 r.intent.setComponent(null);
11933 if (r.curApp != null) {
11934 r.curApp.curReceiver = null;
11935 }
11936 if (r.curFilter != null) {
11937 r.curFilter.receiverList.curBroadcast = null;
11938 }
11939 r.curFilter = null;
11940 r.curApp = null;
11941 r.curComponent = null;
11942 r.curReceiver = null;
11943 mPendingBroadcast = null;
11944
11945 r.resultCode = resultCode;
11946 r.resultData = resultData;
11947 r.resultExtras = resultExtras;
11948 r.resultAbort = resultAbort;
11949
11950 // We will process the next receiver right now if this is finishing
11951 // an app receiver (which is always asynchronous) or after we have
11952 // come back from calling a receiver.
11953 return state == BroadcastRecord.APP_RECEIVE
11954 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11955 }
11956
11957 public void finishReceiver(IBinder who, int resultCode, String resultData,
11958 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011959 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011960
11961 // Refuse possible leaked file descriptors
11962 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11963 throw new IllegalArgumentException("File descriptors passed in Bundle");
11964 }
11965
11966 boolean doNext;
11967
11968 final long origId = Binder.clearCallingIdentity();
11969
11970 synchronized(this) {
11971 doNext = finishReceiverLocked(
11972 who, resultCode, resultData, resultExtras, resultAbort, true);
11973 }
11974
11975 if (doNext) {
11976 processNextBroadcast(false);
11977 }
11978 trimApplications();
11979
11980 Binder.restoreCallingIdentity(origId);
11981 }
11982
Jeff Brown4d94a762010-09-23 11:33:28 -070011983 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011984 if (r.nextReceiver > 0) {
11985 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11986 if (curReceiver instanceof BroadcastFilter) {
11987 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011988 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011989 System.identityHashCode(r),
11990 r.intent.getAction(),
11991 r.nextReceiver - 1,
11992 System.identityHashCode(bf));
11993 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011994 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011995 System.identityHashCode(r),
11996 r.intent.getAction(),
11997 r.nextReceiver - 1,
11998 ((ResolveInfo)curReceiver).toString());
11999 }
12000 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012001 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012002 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012003 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012004 System.identityHashCode(r),
12005 r.intent.getAction(),
12006 r.nextReceiver,
12007 "NONE");
12008 }
12009 }
12010
Jeff Brown4d94a762010-09-23 11:33:28 -070012011 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12012 if (! mPendingBroadcastTimeoutMessage) {
12013 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12014 mHandler.sendMessageAtTime(msg, timeoutTime);
12015 mPendingBroadcastTimeoutMessage = true;
12016 }
12017 }
12018
12019 private final void cancelBroadcastTimeoutLocked() {
12020 if (mPendingBroadcastTimeoutMessage) {
12021 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12022 mPendingBroadcastTimeoutMessage = false;
12023 }
12024 }
12025
12026 private final void broadcastTimeoutLocked(boolean fromMsg) {
12027 if (fromMsg) {
12028 mPendingBroadcastTimeoutMessage = false;
12029 }
12030
12031 if (mOrderedBroadcasts.size() == 0) {
12032 return;
12033 }
12034
12035 long now = SystemClock.uptimeMillis();
12036 BroadcastRecord r = mOrderedBroadcasts.get(0);
12037 if (fromMsg) {
12038 if (mDidDexOpt) {
12039 // Delay timeouts until dexopt finishes.
12040 mDidDexOpt = false;
12041 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12042 setBroadcastTimeoutLocked(timeoutTime);
12043 return;
12044 }
12045 if (! mProcessesReady) {
12046 // Only process broadcast timeouts if the system is ready. That way
12047 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12048 // to do heavy lifting for system up.
12049 return;
12050 }
12051
12052 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12053 if (timeoutTime > now) {
12054 // We can observe premature timeouts because we do not cancel and reset the
12055 // broadcast timeout message after each receiver finishes. Instead, we set up
12056 // an initial timeout then kick it down the road a little further as needed
12057 // when it expires.
12058 if (DEBUG_BROADCAST) Slog.v(TAG,
12059 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12060 + timeoutTime);
12061 setBroadcastTimeoutLocked(timeoutTime);
12062 return;
12063 }
12064 }
12065
12066 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12067 + ", started " + (now - r.receiverTime) + "ms ago");
12068 r.receiverTime = now;
12069 r.anrCount++;
12070
12071 // Current receiver has passed its expiration date.
12072 if (r.nextReceiver <= 0) {
12073 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12074 return;
12075 }
12076
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012077 ProcessRecord app = null;
12078 String anrMessage = null;
12079
Jeff Brown4d94a762010-09-23 11:33:28 -070012080 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12081 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12082 logBroadcastReceiverDiscardLocked(r);
12083 if (curReceiver instanceof BroadcastFilter) {
12084 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12085 if (bf.receiverList.pid != 0
12086 && bf.receiverList.pid != MY_PID) {
12087 synchronized (this.mPidsSelfLocked) {
12088 app = this.mPidsSelfLocked.get(
12089 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012090 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012091 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012092 } else {
12093 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012094 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012095
Jeff Brown4d94a762010-09-23 11:33:28 -070012096 if (app != null) {
12097 anrMessage = "Broadcast of " + r.intent.toString();
12098 }
12099
12100 if (mPendingBroadcast == r) {
12101 mPendingBroadcast = null;
12102 }
12103
12104 // Move on to the next receiver.
12105 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12106 r.resultExtras, r.resultAbort, true);
12107 scheduleBroadcastsLocked();
12108
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012109 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012110 // Post the ANR to the handler since we do not want to process ANRs while
12111 // potentially holding our lock.
12112 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012114 }
12115
12116 private final void processCurBroadcastLocked(BroadcastRecord r,
12117 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012118 if (DEBUG_BROADCAST) Slog.v(TAG,
12119 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012120 if (app.thread == null) {
12121 throw new RemoteException();
12122 }
12123 r.receiver = app.thread.asBinder();
12124 r.curApp = app;
12125 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012126 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012127
12128 // Tell the application to launch this receiver.
12129 r.intent.setComponent(r.curComponent);
12130
12131 boolean started = false;
12132 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012133 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012134 "Delivering to component " + r.curComponent
12135 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012136 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012137 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012138 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012139 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012140 if (DEBUG_BROADCAST) Slog.v(TAG,
12141 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012142 started = true;
12143 } finally {
12144 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012145 if (DEBUG_BROADCAST) Slog.v(TAG,
12146 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012147 r.receiver = null;
12148 r.curApp = null;
12149 app.curReceiver = null;
12150 }
12151 }
12152
12153 }
12154
Jeff Brown4d94a762010-09-23 11:33:28 -070012155 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012156 Intent intent, int resultCode, String data, Bundle extras,
12157 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012158 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012159 if (app != null && app.thread != null) {
12160 // If we have an app thread, do the call through that so it is
12161 // correctly ordered with other one-way calls.
12162 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012163 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012164 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012165 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012166 }
12167 }
12168
Jeff Brown4d94a762010-09-23 11:33:28 -070012169 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012170 BroadcastFilter filter, boolean ordered) {
12171 boolean skip = false;
12172 if (filter.requiredPermission != null) {
12173 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012174 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012175 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012176 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012177 + r.intent.toString()
12178 + " from " + r.callerPackage + " (pid="
12179 + r.callingPid + ", uid=" + r.callingUid + ")"
12180 + " requires " + filter.requiredPermission
12181 + " due to registered receiver " + filter);
12182 skip = true;
12183 }
12184 }
12185 if (r.requiredPermission != null) {
12186 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012187 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012188 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012189 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012190 + r.intent.toString()
12191 + " to " + filter.receiverList.app
12192 + " (pid=" + filter.receiverList.pid
12193 + ", uid=" + filter.receiverList.uid + ")"
12194 + " requires " + r.requiredPermission
12195 + " due to sender " + r.callerPackage
12196 + " (uid " + r.callingUid + ")");
12197 skip = true;
12198 }
12199 }
12200
12201 if (!skip) {
12202 // If this is not being sent as an ordered broadcast, then we
12203 // don't want to touch the fields that keep track of the current
12204 // state of ordered broadcasts.
12205 if (ordered) {
12206 r.receiver = filter.receiverList.receiver.asBinder();
12207 r.curFilter = filter;
12208 filter.receiverList.curBroadcast = r;
12209 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012210 if (filter.receiverList.app != null) {
12211 // Bump hosting application to no longer be in background
12212 // scheduling class. Note that we can't do that if there
12213 // isn't an app... but we can only be in that case for
12214 // things that directly call the IActivityManager API, which
12215 // are already core system stuff so don't matter for this.
12216 r.curApp = filter.receiverList.app;
12217 filter.receiverList.app.curReceiver = r;
12218 updateOomAdjLocked();
12219 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012220 }
12221 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012222 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012223 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012224 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012225 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012226 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012227 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012228 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012229 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012230 if (ordered) {
12231 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12232 }
12233 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012234 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012235 if (ordered) {
12236 r.receiver = null;
12237 r.curFilter = null;
12238 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012239 if (filter.receiverList.app != null) {
12240 filter.receiverList.app.curReceiver = null;
12241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012242 }
12243 }
12244 }
12245 }
12246
Dianne Hackborn12527f92009-11-11 17:39:50 -080012247 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12248 if (r.callingUid < 0) {
12249 // This was from a registerReceiver() call; ignore it.
12250 return;
12251 }
12252 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12253 MAX_BROADCAST_HISTORY-1);
12254 r.finishTime = SystemClock.uptimeMillis();
12255 mBroadcastHistory[0] = r;
12256 }
12257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012258 private final void processNextBroadcast(boolean fromMsg) {
12259 synchronized(this) {
12260 BroadcastRecord r;
12261
Joe Onorato8a9b2202010-02-26 18:56:32 -080012262 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012263 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012264 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012265
12266 updateCpuStats();
12267
12268 if (fromMsg) {
12269 mBroadcastsScheduled = false;
12270 }
12271
12272 // First, deliver any non-serialized broadcasts right away.
12273 while (mParallelBroadcasts.size() > 0) {
12274 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012275 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012276 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012277 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012278 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012279 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012280 for (int i=0; i<N; i++) {
12281 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012282 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012283 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012284 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012285 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012286 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012287 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012288 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012289 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012290 }
12291
12292 // Now take care of the next serialized one...
12293
12294 // If we are waiting for a process to come up to handle the next
12295 // broadcast, then do nothing at this point. Just in case, we
12296 // check that the process we're waiting for still exists.
12297 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012298 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012299 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012300 + mPendingBroadcast.curApp);
12301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012302
12303 boolean isDead;
12304 synchronized (mPidsSelfLocked) {
12305 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12306 }
12307 if (!isDead) {
12308 // It's still alive, so keep waiting
12309 return;
12310 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012311 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012312 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012313 mPendingBroadcast.state = BroadcastRecord.IDLE;
12314 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012315 mPendingBroadcast = null;
12316 }
12317 }
12318
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012319 boolean looped = false;
12320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012321 do {
12322 if (mOrderedBroadcasts.size() == 0) {
12323 // No more broadcasts pending, so all done!
12324 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012325 if (looped) {
12326 // If we had finished the last ordered broadcast, then
12327 // make sure all processes have correct oom and sched
12328 // adjustments.
12329 updateOomAdjLocked();
12330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012331 return;
12332 }
12333 r = mOrderedBroadcasts.get(0);
12334 boolean forceReceive = false;
12335
12336 // Ensure that even if something goes awry with the timeout
12337 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012338 // and continue to make progress.
12339 //
12340 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012341 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012342 // one time heavy lifting after system upgrades and can take
12343 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012344 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012345 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012346 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012347 if ((numReceivers > 0) &&
12348 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012349 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012350 + " now=" + now
12351 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012352 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012353 + " intent=" + r.intent
12354 + " numReceivers=" + numReceivers
12355 + " nextReceiver=" + r.nextReceiver
12356 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012357 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012358 forceReceive = true;
12359 r.state = BroadcastRecord.IDLE;
12360 }
12361 }
12362
12363 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012364 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012365 "processNextBroadcast() called when not idle (state="
12366 + r.state + ")");
12367 return;
12368 }
12369
12370 if (r.receivers == null || r.nextReceiver >= numReceivers
12371 || r.resultAbort || forceReceive) {
12372 // No more receivers for this broadcast! Send the final
12373 // result if requested...
12374 if (r.resultTo != null) {
12375 try {
12376 if (DEBUG_BROADCAST) {
12377 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012378 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012379 + " seq=" + seq + " app=" + r.callerApp);
12380 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012381 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012382 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012383 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012384 // Set this to null so that the reference
12385 // (local and remote) isnt kept in the mBroadcastHistory.
12386 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012387 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012388 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012389 }
12390 }
12391
Joe Onorato8a9b2202010-02-26 18:56:32 -080012392 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012393 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012394
Joe Onorato8a9b2202010-02-26 18:56:32 -080012395 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012396 + r);
12397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012398 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012399 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012400 mOrderedBroadcasts.remove(0);
12401 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012402 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012403 continue;
12404 }
12405 } while (r == null);
12406
12407 // Get the next receiver...
12408 int recIdx = r.nextReceiver++;
12409
12410 // Keep track of when this receiver started, and make sure there
12411 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012412 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012413 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012414 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012415 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012416 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012417 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012418 }
12419 if (! mPendingBroadcastTimeoutMessage) {
12420 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012421 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012422 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12423 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012424 }
12425
12426 Object nextReceiver = r.receivers.get(recIdx);
12427 if (nextReceiver instanceof BroadcastFilter) {
12428 // Simple case: this is a registered receiver who gets
12429 // a direct call.
12430 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012431 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012432 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012433 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012434 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012435 if (r.receiver == null || !r.ordered) {
12436 // The receiver has already finished, so schedule to
12437 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012438 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12439 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012440 r.state = BroadcastRecord.IDLE;
12441 scheduleBroadcastsLocked();
12442 }
12443 return;
12444 }
12445
12446 // Hard case: need to instantiate the receiver, possibly
12447 // starting its application process to host it.
12448
12449 ResolveInfo info =
12450 (ResolveInfo)nextReceiver;
12451
12452 boolean skip = false;
12453 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012454 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12455 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012456 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012457 if (!info.activityInfo.exported) {
12458 Slog.w(TAG, "Permission Denial: broadcasting "
12459 + r.intent.toString()
12460 + " from " + r.callerPackage + " (pid=" + r.callingPid
12461 + ", uid=" + r.callingUid + ")"
12462 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12463 + " due to receiver " + info.activityInfo.packageName
12464 + "/" + info.activityInfo.name);
12465 } else {
12466 Slog.w(TAG, "Permission Denial: broadcasting "
12467 + r.intent.toString()
12468 + " from " + r.callerPackage + " (pid=" + r.callingPid
12469 + ", uid=" + r.callingUid + ")"
12470 + " requires " + info.activityInfo.permission
12471 + " due to receiver " + info.activityInfo.packageName
12472 + "/" + info.activityInfo.name);
12473 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012474 skip = true;
12475 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012476 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012477 r.requiredPermission != null) {
12478 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012479 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012480 checkPermission(r.requiredPermission,
12481 info.activityInfo.applicationInfo.packageName);
12482 } catch (RemoteException e) {
12483 perm = PackageManager.PERMISSION_DENIED;
12484 }
12485 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012486 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012487 + r.intent + " to "
12488 + info.activityInfo.applicationInfo.packageName
12489 + " requires " + r.requiredPermission
12490 + " due to sender " + r.callerPackage
12491 + " (uid " + r.callingUid + ")");
12492 skip = true;
12493 }
12494 }
12495 if (r.curApp != null && r.curApp.crashing) {
12496 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012497 if (DEBUG_BROADCAST) Slog.v(TAG,
12498 "Skipping deliver ordered " + r + " to " + r.curApp
12499 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012500 skip = true;
12501 }
12502
12503 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012504 if (DEBUG_BROADCAST) Slog.v(TAG,
12505 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012506 r.receiver = null;
12507 r.curFilter = null;
12508 r.state = BroadcastRecord.IDLE;
12509 scheduleBroadcastsLocked();
12510 return;
12511 }
12512
12513 r.state = BroadcastRecord.APP_RECEIVE;
12514 String targetProcess = info.activityInfo.processName;
12515 r.curComponent = new ComponentName(
12516 info.activityInfo.applicationInfo.packageName,
12517 info.activityInfo.name);
12518 r.curReceiver = info.activityInfo;
12519
Dianne Hackborne7f97212011-02-24 14:40:20 -080012520 // Broadcast is being executed, its package can't be stopped.
12521 try {
12522 AppGlobals.getPackageManager().setPackageStoppedState(
12523 r.curComponent.getPackageName(), false);
12524 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012525 } catch (IllegalArgumentException e) {
12526 Slog.w(TAG, "Failed trying to unstop package "
12527 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012528 }
12529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012530 // Is this receiver's application already running?
12531 ProcessRecord app = getProcessRecordLocked(targetProcess,
12532 info.activityInfo.applicationInfo.uid);
12533 if (app != null && app.thread != null) {
12534 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012535 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012536 processCurBroadcastLocked(r, app);
12537 return;
12538 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012539 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012540 + r.curComponent, e);
12541 }
12542
12543 // If a dead object exception was thrown -- fall through to
12544 // restart the application.
12545 }
12546
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012547 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012548 if (DEBUG_BROADCAST) Slog.v(TAG,
12549 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012550 if ((r.curApp=startProcessLocked(targetProcess,
12551 info.activityInfo.applicationInfo, true,
12552 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012553 "broadcast", r.curComponent,
12554 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12555 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012556 // Ah, this recipient is unavailable. Finish it if necessary,
12557 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012558 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012559 + info.activityInfo.applicationInfo.packageName + "/"
12560 + info.activityInfo.applicationInfo.uid + " for broadcast "
12561 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012562 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012563 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12564 r.resultExtras, r.resultAbort, true);
12565 scheduleBroadcastsLocked();
12566 r.state = BroadcastRecord.IDLE;
12567 return;
12568 }
12569
12570 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012571 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012572 }
12573 }
12574
12575 // =========================================================
12576 // INSTRUMENTATION
12577 // =========================================================
12578
12579 public boolean startInstrumentation(ComponentName className,
12580 String profileFile, int flags, Bundle arguments,
12581 IInstrumentationWatcher watcher) {
12582 // Refuse possible leaked file descriptors
12583 if (arguments != null && arguments.hasFileDescriptors()) {
12584 throw new IllegalArgumentException("File descriptors passed in Bundle");
12585 }
12586
12587 synchronized(this) {
12588 InstrumentationInfo ii = null;
12589 ApplicationInfo ai = null;
12590 try {
12591 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012592 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012593 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012594 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012595 } catch (PackageManager.NameNotFoundException e) {
12596 }
12597 if (ii == null) {
12598 reportStartInstrumentationFailure(watcher, className,
12599 "Unable to find instrumentation info for: " + className);
12600 return false;
12601 }
12602 if (ai == null) {
12603 reportStartInstrumentationFailure(watcher, className,
12604 "Unable to find instrumentation target package: " + ii.targetPackage);
12605 return false;
12606 }
12607
12608 int match = mContext.getPackageManager().checkSignatures(
12609 ii.targetPackage, ii.packageName);
12610 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12611 String msg = "Permission Denial: starting instrumentation "
12612 + className + " from pid="
12613 + Binder.getCallingPid()
12614 + ", uid=" + Binder.getCallingPid()
12615 + " not allowed because package " + ii.packageName
12616 + " does not have a signature matching the target "
12617 + ii.targetPackage;
12618 reportStartInstrumentationFailure(watcher, className, msg);
12619 throw new SecurityException(msg);
12620 }
12621
12622 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012623 // Instrumentation can kill and relaunch even persistent processes
12624 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012625 ProcessRecord app = addAppLocked(ai);
12626 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012627 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012628 app.instrumentationProfileFile = profileFile;
12629 app.instrumentationArguments = arguments;
12630 app.instrumentationWatcher = watcher;
12631 app.instrumentationResultClass = className;
12632 Binder.restoreCallingIdentity(origId);
12633 }
12634
12635 return true;
12636 }
12637
12638 /**
12639 * Report errors that occur while attempting to start Instrumentation. Always writes the
12640 * error to the logs, but if somebody is watching, send the report there too. This enables
12641 * the "am" command to report errors with more information.
12642 *
12643 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12644 * @param cn The component name of the instrumentation.
12645 * @param report The error report.
12646 */
12647 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12648 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012649 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012650 try {
12651 if (watcher != null) {
12652 Bundle results = new Bundle();
12653 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12654 results.putString("Error", report);
12655 watcher.instrumentationStatus(cn, -1, results);
12656 }
12657 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012658 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012659 }
12660 }
12661
12662 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12663 if (app.instrumentationWatcher != null) {
12664 try {
12665 // NOTE: IInstrumentationWatcher *must* be oneway here
12666 app.instrumentationWatcher.instrumentationFinished(
12667 app.instrumentationClass,
12668 resultCode,
12669 results);
12670 } catch (RemoteException e) {
12671 }
12672 }
12673 app.instrumentationWatcher = null;
12674 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012675 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012676 app.instrumentationProfileFile = null;
12677 app.instrumentationArguments = null;
12678
Christopher Tate3dacd842011-08-19 14:56:15 -070012679 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012680 }
12681
12682 public void finishInstrumentation(IApplicationThread target,
12683 int resultCode, Bundle results) {
12684 // Refuse possible leaked file descriptors
12685 if (results != null && results.hasFileDescriptors()) {
12686 throw new IllegalArgumentException("File descriptors passed in Intent");
12687 }
12688
12689 synchronized(this) {
12690 ProcessRecord app = getRecordForAppLocked(target);
12691 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012692 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012693 return;
12694 }
12695 final long origId = Binder.clearCallingIdentity();
12696 finishInstrumentationLocked(app, resultCode, results);
12697 Binder.restoreCallingIdentity(origId);
12698 }
12699 }
12700
12701 // =========================================================
12702 // CONFIGURATION
12703 // =========================================================
12704
12705 public ConfigurationInfo getDeviceConfigurationInfo() {
12706 ConfigurationInfo config = new ConfigurationInfo();
12707 synchronized (this) {
12708 config.reqTouchScreen = mConfiguration.touchscreen;
12709 config.reqKeyboardType = mConfiguration.keyboard;
12710 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012711 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12712 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012713 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12714 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012715 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12716 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012717 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12718 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012719 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012720 }
12721 return config;
12722 }
12723
12724 public Configuration getConfiguration() {
12725 Configuration ci;
12726 synchronized(this) {
12727 ci = new Configuration(mConfiguration);
12728 }
12729 return ci;
12730 }
12731
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012732 public void updatePersistentConfiguration(Configuration values) {
12733 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12734 "updateConfiguration()");
12735 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12736 "updateConfiguration()");
12737 if (values == null) {
12738 throw new NullPointerException("Configuration must not be null");
12739 }
12740
12741 synchronized(this) {
12742 final long origId = Binder.clearCallingIdentity();
12743 updateConfigurationLocked(values, null, true);
12744 Binder.restoreCallingIdentity(origId);
12745 }
12746 }
12747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012748 public void updateConfiguration(Configuration values) {
12749 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12750 "updateConfiguration()");
12751
12752 synchronized(this) {
12753 if (values == null && mWindowManager != null) {
12754 // sentinel: fetch the current configuration from the window manager
12755 values = mWindowManager.computeNewConfiguration();
12756 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012757
12758 if (mWindowManager != null) {
12759 mProcessList.applyDisplaySize(mWindowManager);
12760 }
12761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012762 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012763 if (values != null) {
12764 Settings.System.clearConfiguration(values);
12765 }
12766 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012767 Binder.restoreCallingIdentity(origId);
12768 }
12769 }
12770
12771 /**
12772 * Do either or both things: (1) change the current configuration, and (2)
12773 * make sure the given activity is running with the (now) current
12774 * configuration. Returns true if the activity has been left running, or
12775 * false if <var>starting</var> is being destroyed to match the new
12776 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012777 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012778 */
12779 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012780 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012781 int changes = 0;
12782
12783 boolean kept = true;
12784
12785 if (values != null) {
12786 Configuration newConfig = new Configuration(mConfiguration);
12787 changes = newConfig.updateFrom(values);
12788 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012789 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012790 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012791 }
12792
Doug Zongker2bec3d42009-12-04 12:52:44 -080012793 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012794
12795 if (values.locale != null) {
12796 saveLocaleLocked(values.locale,
12797 !values.locale.equals(mConfiguration.locale),
12798 values.userSetLocale);
12799 }
12800
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012801 mConfigurationSeq++;
12802 if (mConfigurationSeq <= 0) {
12803 mConfigurationSeq = 1;
12804 }
12805 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012806 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012807 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012808
12809 AttributeCache ac = AttributeCache.instance();
12810 if (ac != null) {
12811 ac.updateConfiguration(mConfiguration);
12812 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012813
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012814 // Make sure all resources in our process are updated
12815 // right now, so that anyone who is going to retrieve
12816 // resource values after we return will be sure to get
12817 // the new ones. This is especially important during
12818 // boot, where the first config change needs to guarantee
12819 // all resources have that config before following boot
12820 // code is executed.
12821 mSystemThread.applyConfigurationToResources(newConfig);
12822
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012823 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012824 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12825 msg.obj = new Configuration(mConfiguration);
12826 mHandler.sendMessage(msg);
12827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012828
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012829 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12830 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012831 try {
12832 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012833 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012834 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012835 app.thread.scheduleConfigurationChanged(mConfiguration);
12836 }
12837 } catch (Exception e) {
12838 }
12839 }
12840 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012841 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12842 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012843 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12844 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012845 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12846 broadcastIntentLocked(null, null,
12847 new Intent(Intent.ACTION_LOCALE_CHANGED),
12848 null, null, 0, null, null,
12849 null, false, false, MY_PID, Process.SYSTEM_UID);
12850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012851 }
12852 }
12853
12854 if (changes != 0 && starting == null) {
12855 // If the configuration changed, and the caller is not already
12856 // in the process of starting an activity, then find the top
12857 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012858 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012859 }
12860
12861 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012862 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012863 // And we need to make sure at this point that all other activities
12864 // are made visible with the correct configuration.
12865 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012866 }
12867
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012868 if (values != null && mWindowManager != null) {
12869 mWindowManager.setNewConfiguration(mConfiguration);
12870 }
12871
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012872 return kept;
12873 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012874
12875 /**
12876 * Save the locale. You must be inside a synchronized (this) block.
12877 */
12878 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12879 if(isDiff) {
12880 SystemProperties.set("user.language", l.getLanguage());
12881 SystemProperties.set("user.region", l.getCountry());
12882 }
12883
12884 if(isPersist) {
12885 SystemProperties.set("persist.sys.language", l.getLanguage());
12886 SystemProperties.set("persist.sys.country", l.getCountry());
12887 SystemProperties.set("persist.sys.localevar", l.getVariant());
12888 }
12889 }
12890
12891 // =========================================================
12892 // LIFETIME MANAGEMENT
12893 // =========================================================
12894
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012895 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12896 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012897 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012898 // This adjustment has already been computed. If we are calling
12899 // from the top, we may have already computed our adjustment with
12900 // an earlier hidden adjustment that isn't really for us... if
12901 // so, use the new hidden adjustment.
12902 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012903 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012904 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012905 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012906 }
12907
12908 if (app.thread == null) {
12909 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012910 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012911 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012912 }
12913
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012914 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12915 app.adjSource = null;
12916 app.adjTarget = null;
12917 app.empty = false;
12918 app.hidden = false;
12919
12920 final int activitiesSize = app.activities.size();
12921
Dianne Hackborn7d608422011-08-07 16:24:18 -070012922 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012923 // The max adjustment doesn't allow this app to be anything
12924 // below foreground, so it is not worth doing work for it.
12925 app.adjType = "fixed";
12926 app.adjSeq = mAdjSeq;
12927 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012928 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012929 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012930 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012931 // System process can do UI, and when they do we want to have
12932 // them trim their memory after the user leaves the UI. To
12933 // facilitate this, here we need to determine whether or not it
12934 // is currently showing UI.
12935 app.systemNoUi = true;
12936 if (app == TOP_APP) {
12937 app.systemNoUi = false;
12938 } else if (activitiesSize > 0) {
12939 for (int j = 0; j < activitiesSize; j++) {
12940 final ActivityRecord r = app.activities.get(j);
12941 if (r.visible) {
12942 app.systemNoUi = false;
12943 break;
12944 }
12945 }
12946 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012947 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012948 }
12949
12950 final boolean hadForegroundActivities = app.foregroundActivities;
12951
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012952 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012953 app.keeping = false;
12954 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012955
The Android Open Source Project4df24232009-03-05 14:34:35 -080012956 // Determine the importance of the process, starting with most
12957 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012958 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012959 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012960 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012961 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012962 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012963 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012964 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012965 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012966 } else if (app.instrumentationClass != null) {
12967 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012968 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012969 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012970 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012971 } else if (app.curReceiver != null ||
12972 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12973 // An app that is currently receiving a broadcast also
12974 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012975 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012976 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012977 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012978 } else if (app.executingServices.size() > 0) {
12979 // An app that is currently executing a service callback also
12980 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012981 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012982 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012983 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012984 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012985 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012986 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012987 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012988 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012989 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012990 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012991 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012992 // A very not-needed process. If this is lower in the lru list,
12993 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012994 adj = hiddenAdj;
12995 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012996 app.hidden = true;
12997 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012998 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012999 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013000
13001 // Examine all activities if not already foreground.
13002 if (!app.foregroundActivities && activitiesSize > 0) {
13003 for (int j = 0; j < activitiesSize; j++) {
13004 final ActivityRecord r = app.activities.get(j);
13005 if (r.visible) {
13006 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013007 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13008 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013009 app.adjType = "visible";
13010 }
13011 schedGroup = Process.THREAD_GROUP_DEFAULT;
13012 app.hidden = false;
13013 app.foregroundActivities = true;
13014 break;
13015 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13016 || r.state == ActivityState.STOPPING) {
13017 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013018 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13019 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013020 app.adjType = "stopping";
13021 }
13022 app.foregroundActivities = true;
13023 }
13024 }
13025 }
13026
Dianne Hackborn7d608422011-08-07 16:24:18 -070013027 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013028 if (app.foregroundServices) {
13029 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013030 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013031 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013032 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013033 } else if (app.forcingToForeground != null) {
13034 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013035 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013036 app.adjType = "force-foreground";
13037 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013038 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013039 }
13040 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013041
Dianne Hackborn7d608422011-08-07 16:24:18 -070013042 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013043 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013044 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013045 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13046 app.adjType = "heavy";
13047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013048
Dianne Hackborn7d608422011-08-07 16:24:18 -070013049 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013050 // This process is hosting what we currently consider to be the
13051 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013052 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013053 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13054 app.adjType = "home";
13055 }
13056
Joe Onorato8a9b2202010-02-26 18:56:32 -080013057 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013058
The Android Open Source Project4df24232009-03-05 14:34:35 -080013059 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013060 // there are applications dependent on our services or providers, but
13061 // this gives us a baseline and makes sure we don't get into an
13062 // infinite recursion.
13063 app.adjSeq = mAdjSeq;
13064 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013065
Christopher Tate6fa95972009-06-05 18:43:55 -070013066 if (mBackupTarget != null && app == mBackupTarget.app) {
13067 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013068 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013069 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013070 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013071 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013072 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013073 }
13074 }
13075
Dianne Hackborn7d608422011-08-07 16:24:18 -070013076 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013077 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013078 final long now = SystemClock.uptimeMillis();
13079 // This process is more important if the top activity is
13080 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013081 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013082 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013083 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013084 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013085 if (app.hasShownUi) {
13086 // If this process has shown some UI, let it immediately
13087 // go to the LRU list because it may be pretty heavy with
13088 // UI stuff. We'll tag it with a label just to help
13089 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013090 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013091 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013092 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013093 } else {
13094 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13095 // This service has seen some activity within
13096 // recent memory, so we will keep its process ahead
13097 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013098 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
13099 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013100 app.adjType = "started-services";
13101 app.hidden = false;
13102 }
13103 }
13104 // If we have let the service slide into the background
13105 // state, still have some text describing what it is doing
13106 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013107 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013108 app.adjType = "started-bg-services";
13109 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013110 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013111 // Don't kill this process because it is doing work; it
13112 // has said it is doing work.
13113 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013114 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013115 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013116 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013117 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013118 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013119 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013120 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013121 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013122 // XXX should compute this based on the max of
13123 // all connected clients.
13124 ConnectionRecord cr = clist.get(i);
13125 if (cr.binding.client == app) {
13126 // Binding to ourself is not interesting.
13127 continue;
13128 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013129 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013130 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013131 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013132 int myHiddenAdj = hiddenAdj;
13133 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013134 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013135 myHiddenAdj = client.hiddenAdj;
13136 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013137 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013138 }
13139 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013140 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013141 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013142 String adjType = null;
13143 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13144 // Not doing bind OOM management, so treat
13145 // this guy more like a started service.
13146 if (app.hasShownUi) {
13147 // If this process has shown some UI, let it immediately
13148 // go to the LRU list because it may be pretty heavy with
13149 // UI stuff. We'll tag it with a label just to help
13150 // debug and understand what is going on.
13151 if (adj > clientAdj) {
13152 adjType = "bound-bg-ui-services";
13153 }
13154 clientAdj = adj;
13155 } else {
13156 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13157 // This service has not seen activity within
13158 // recent memory, so allow it to drop to the
13159 // LRU list if there is no other reason to keep
13160 // it around. We'll also tag it with a label just
13161 // to help debug and undertand what is going on.
13162 if (adj > clientAdj) {
13163 adjType = "bound-bg-services";
13164 }
13165 clientAdj = adj;
13166 }
13167 }
13168 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013169 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013170 // If this process has recently shown UI, and
13171 // the process that is binding to it is less
13172 // important than being visible, then we don't
13173 // care about the binding as much as we care
13174 // about letting this process get into the LRU
13175 // list to be killed and restarted if needed for
13176 // memory.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013177 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013178 adjType = "bound-bg-ui-services";
13179 } else {
13180 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13181 |Context.BIND_IMPORTANT)) != 0) {
13182 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013183 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013184 adj = clientAdj;
13185 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013186 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013187 }
13188 if (!client.hidden) {
13189 app.hidden = false;
13190 }
13191 if (client.keeping) {
13192 app.keeping = true;
13193 }
13194 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013195 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013196 }
13197 if (adjType != null) {
13198 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013199 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13200 .REASON_SERVICE_IN_USE;
13201 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013202 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013203 app.adjTarget = s.name;
13204 }
13205 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13206 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13207 schedGroup = Process.THREAD_GROUP_DEFAULT;
13208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013209 }
13210 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013211 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13212 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013213 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013214 (a.visible || a.state == ActivityState.RESUMED
13215 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013216 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013217 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13218 schedGroup = Process.THREAD_GROUP_DEFAULT;
13219 }
13220 app.hidden = false;
13221 app.adjType = "service";
13222 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13223 .REASON_SERVICE_IN_USE;
13224 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013225 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013226 app.adjTarget = s.name;
13227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013228 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013229 }
13230 }
13231 }
13232 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013233
Dianne Hackborn287952c2010-09-22 22:34:31 -070013234 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013235 // would like to avoid killing it unless it would prevent the current
13236 // application from running. By default we put the process in
13237 // with the rest of the background processes; as we scan through
13238 // its services we may bump it up from there.
13239 if (adj > hiddenAdj) {
13240 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013241 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013242 app.adjType = "bg-services";
13243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013244 }
13245
Dianne Hackborn7d608422011-08-07 16:24:18 -070013246 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013247 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013248 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013249 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013250 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013251 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013252 if (cpr.clients.size() != 0) {
13253 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013254 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013255 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013256 if (client == app) {
13257 // Being our own client is not interesting.
13258 continue;
13259 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013260 int myHiddenAdj = hiddenAdj;
13261 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013262 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013263 myHiddenAdj = client.hiddenAdj;
13264 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013265 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013266 }
13267 }
13268 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013269 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013270 if (adj > clientAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013271 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013272 app.adjType = "bg-ui-provider";
13273 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013274 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13275 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013276 app.adjType = "provider";
13277 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013278 if (!client.hidden) {
13279 app.hidden = false;
13280 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013281 if (client.keeping) {
13282 app.keeping = true;
13283 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013284 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13285 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013286 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013287 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013288 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013289 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013290 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13291 schedGroup = Process.THREAD_GROUP_DEFAULT;
13292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013293 }
13294 }
13295 // If the provider has external (non-framework) process
13296 // dependencies, ensure that its adjustment is at least
13297 // FOREGROUND_APP_ADJ.
13298 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013299 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13300 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013301 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013302 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013303 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013304 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013305 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013306 }
13307 }
13308 }
13309 }
13310
13311 app.curRawAdj = adj;
13312
Joe Onorato8a9b2202010-02-26 18:56:32 -080013313 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013314 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13315 if (adj > app.maxAdj) {
13316 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013317 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013318 schedGroup = Process.THREAD_GROUP_DEFAULT;
13319 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013320 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013321 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013322 app.keeping = true;
13323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013324
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013325 if (app.hasAboveClient) {
13326 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13327 // then we need to drop its adjustment to be lower than the service's
13328 // in order to honor the request. We want to drop it by one adjustment
13329 // level... but there is special meaning applied to various levels so
13330 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013331 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013332 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013333 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13334 adj = ProcessList.VISIBLE_APP_ADJ;
13335 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13336 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13337 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13338 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13339 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013340 adj++;
13341 }
13342 }
13343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013344 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013345 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013346
13347 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013348 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13349 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013350 }
13351
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013352 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013353 }
13354
13355 /**
13356 * Ask a given process to GC right now.
13357 */
13358 final void performAppGcLocked(ProcessRecord app) {
13359 try {
13360 app.lastRequestedGc = SystemClock.uptimeMillis();
13361 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013362 if (app.reportLowMemory) {
13363 app.reportLowMemory = false;
13364 app.thread.scheduleLowMemory();
13365 } else {
13366 app.thread.processInBackground();
13367 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013368 }
13369 } catch (Exception e) {
13370 // whatever.
13371 }
13372 }
13373
13374 /**
13375 * Returns true if things are idle enough to perform GCs.
13376 */
Josh Bartel7f208742010-02-25 11:01:44 -060013377 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013378 return mParallelBroadcasts.size() == 0
13379 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013380 && (mSleeping || (mMainStack.mResumedActivity != null &&
13381 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013382 }
13383
13384 /**
13385 * Perform GCs on all processes that are waiting for it, but only
13386 * if things are idle.
13387 */
13388 final void performAppGcsLocked() {
13389 final int N = mProcessesToGc.size();
13390 if (N <= 0) {
13391 return;
13392 }
Josh Bartel7f208742010-02-25 11:01:44 -060013393 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013394 while (mProcessesToGc.size() > 0) {
13395 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013396 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013397 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13398 <= SystemClock.uptimeMillis()) {
13399 // To avoid spamming the system, we will GC processes one
13400 // at a time, waiting a few seconds between each.
13401 performAppGcLocked(proc);
13402 scheduleAppGcsLocked();
13403 return;
13404 } else {
13405 // It hasn't been long enough since we last GCed this
13406 // process... put it in the list to wait for its time.
13407 addProcessToGcListLocked(proc);
13408 break;
13409 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013410 }
13411 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013412
13413 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013414 }
13415 }
13416
13417 /**
13418 * If all looks good, perform GCs on all processes waiting for them.
13419 */
13420 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013421 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013422 performAppGcsLocked();
13423 return;
13424 }
13425 // Still not idle, wait some more.
13426 scheduleAppGcsLocked();
13427 }
13428
13429 /**
13430 * Schedule the execution of all pending app GCs.
13431 */
13432 final void scheduleAppGcsLocked() {
13433 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013434
13435 if (mProcessesToGc.size() > 0) {
13436 // Schedule a GC for the time to the next process.
13437 ProcessRecord proc = mProcessesToGc.get(0);
13438 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13439
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013440 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013441 long now = SystemClock.uptimeMillis();
13442 if (when < (now+GC_TIMEOUT)) {
13443 when = now + GC_TIMEOUT;
13444 }
13445 mHandler.sendMessageAtTime(msg, when);
13446 }
13447 }
13448
13449 /**
13450 * Add a process to the array of processes waiting to be GCed. Keeps the
13451 * list in sorted order by the last GC time. The process can't already be
13452 * on the list.
13453 */
13454 final void addProcessToGcListLocked(ProcessRecord proc) {
13455 boolean added = false;
13456 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13457 if (mProcessesToGc.get(i).lastRequestedGc <
13458 proc.lastRequestedGc) {
13459 added = true;
13460 mProcessesToGc.add(i+1, proc);
13461 break;
13462 }
13463 }
13464 if (!added) {
13465 mProcessesToGc.add(0, proc);
13466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013467 }
13468
13469 /**
13470 * Set up to ask a process to GC itself. This will either do it
13471 * immediately, or put it on the list of processes to gc the next
13472 * time things are idle.
13473 */
13474 final void scheduleAppGcLocked(ProcessRecord app) {
13475 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013476 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013477 return;
13478 }
13479 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013480 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013481 scheduleAppGcsLocked();
13482 }
13483 }
13484
Dianne Hackborn287952c2010-09-22 22:34:31 -070013485 final void checkExcessivePowerUsageLocked(boolean doKills) {
13486 updateCpuStatsNow();
13487
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013488 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013489 boolean doWakeKills = doKills;
13490 boolean doCpuKills = doKills;
13491 if (mLastPowerCheckRealtime == 0) {
13492 doWakeKills = false;
13493 }
13494 if (mLastPowerCheckUptime == 0) {
13495 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013496 }
13497 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013498 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013499 }
13500 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013501 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13502 final long curUptime = SystemClock.uptimeMillis();
13503 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13504 mLastPowerCheckRealtime = curRealtime;
13505 mLastPowerCheckUptime = curUptime;
13506 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13507 doWakeKills = false;
13508 }
13509 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13510 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013511 }
13512 int i = mLruProcesses.size();
13513 while (i > 0) {
13514 i--;
13515 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013516 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013517 long wtime;
13518 synchronized (stats) {
13519 wtime = stats.getProcessWakeTime(app.info.uid,
13520 app.pid, curRealtime);
13521 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013522 long wtimeUsed = wtime - app.lastWakeTime;
13523 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13524 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013525 StringBuilder sb = new StringBuilder(128);
13526 sb.append("Wake for ");
13527 app.toShortString(sb);
13528 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013529 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013530 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013531 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013532 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013533 sb.append((wtimeUsed*100)/realtimeSince);
13534 sb.append("%)");
13535 Slog.i(TAG, sb.toString());
13536 sb.setLength(0);
13537 sb.append("CPU for ");
13538 app.toShortString(sb);
13539 sb.append(": over ");
13540 TimeUtils.formatDuration(uptimeSince, sb);
13541 sb.append(" used ");
13542 TimeUtils.formatDuration(cputimeUsed, sb);
13543 sb.append(" (");
13544 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013545 sb.append("%)");
13546 Slog.i(TAG, sb.toString());
13547 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013548 // If a process has held a wake lock for more
13549 // than 50% of the time during this period,
13550 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013551 if (doWakeKills && realtimeSince > 0
13552 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13553 synchronized (stats) {
13554 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13555 realtimeSince, wtimeUsed);
13556 }
13557 Slog.w(TAG, "Excessive wake lock in " + app.processName
13558 + " (pid " + app.pid + "): held " + wtimeUsed
13559 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013560 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13561 app.processName, app.setAdj, "excessive wake lock");
13562 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013563 } else if (doCpuKills && uptimeSince > 0
13564 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13565 synchronized (stats) {
13566 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13567 uptimeSince, cputimeUsed);
13568 }
13569 Slog.w(TAG, "Excessive CPU in " + app.processName
13570 + " (pid " + app.pid + "): used " + cputimeUsed
13571 + " during " + uptimeSince);
13572 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13573 app.processName, app.setAdj, "excessive cpu");
13574 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013575 } else {
13576 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013577 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013578 }
13579 }
13580 }
13581 }
13582
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013583 private final boolean updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013584 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013585 app.hiddenAdj = hiddenAdj;
13586
13587 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013588 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013589 }
13590
Dianne Hackborn287952c2010-09-22 22:34:31 -070013591 final boolean wasKeeping = app.keeping;
13592
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013593 boolean success = true;
13594
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013595 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013596
Jeff Brown10e89712011-07-08 18:52:57 -070013597 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070013598 if (false) {
13599 // Removing for now. Forcing GCs is not so useful anymore
13600 // with Dalvik, and the new memory level hint facility is
13601 // better for what we need to do these days.
13602 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13603 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13604 // If this app is transitioning from foreground to
13605 // non-foreground, have it do a gc.
13606 scheduleAppGcLocked(app);
13607 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13608 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13609 // Likewise do a gc when an app is moving in to the
13610 // background (such as a service stopping).
13611 scheduleAppGcLocked(app);
13612 }
Jeff Brown10e89712011-07-08 18:52:57 -070013613 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013614
Jeff Brown10e89712011-07-08 18:52:57 -070013615 if (wasKeeping && !app.keeping) {
13616 // This app is no longer something we want to keep. Note
13617 // its current wake lock time to later know to kill it if
13618 // it is not behaving well.
13619 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13620 synchronized (stats) {
13621 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13622 app.pid, SystemClock.elapsedRealtime());
13623 }
13624 app.lastCpuTime = app.curCpuTime;
13625 }
13626
13627 app.setRawAdj = app.curRawAdj;
13628 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013629 if (app.curAdj != app.setAdj) {
13630 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013631 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13632 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013633 " oom adj to " + app.curAdj + " because " + app.adjType);
13634 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013635 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013636 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013637 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013638 }
13639 }
13640 if (app.setSchedGroup != app.curSchedGroup) {
13641 app.setSchedGroup = app.curSchedGroup;
13642 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13643 "Setting process group of " + app.processName
13644 + " to " + app.curSchedGroup);
13645 if (app.waitingToKill != null &&
13646 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13647 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13648 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13649 app.processName, app.setAdj, app.waitingToKill);
13650 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013651 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013652 } else {
13653 if (true) {
13654 long oldId = Binder.clearCallingIdentity();
13655 try {
13656 Process.setProcessGroup(app.pid, app.curSchedGroup);
13657 } catch (Exception e) {
13658 Slog.w(TAG, "Failed setting process group of " + app.pid
13659 + " to " + app.curSchedGroup);
13660 e.printStackTrace();
13661 } finally {
13662 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013663 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013664 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013665 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013666 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013667 app.thread.setSchedulingGroup(app.curSchedGroup);
13668 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013669 }
13670 }
13671 }
13672 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013673 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013674 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013675 }
13676
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013677 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013678 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013679 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013680 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013681 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013682 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013683 }
13684 }
13685 return resumedActivity;
13686 }
13687
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013688 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013689 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013690 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13691 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013692 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13693 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013694
13695 mAdjSeq++;
13696
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013697 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013698 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13699 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013700 if (nowHidden != wasHidden) {
13701 // Changed to/from hidden state, so apps after it in the LRU
13702 // list may also be changed.
13703 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013704 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013705 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013706 }
13707
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013708 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013709 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013710 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13711
13712 if (false) {
13713 RuntimeException e = new RuntimeException();
13714 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013715 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013716 }
13717
13718 mAdjSeq++;
13719
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013720 // Let's determine how many processes we have running vs.
13721 // how many slots we have for background processes; we may want
13722 // to put multiple processes in a slot of there are enough of
13723 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013724 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013725 int factor = (mLruProcesses.size()-4)/numSlots;
13726 if (factor < 1) factor = 1;
13727 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013728 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013729
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013730 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013731 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013732 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013733 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013734 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013735 while (i > 0) {
13736 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013737 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013738 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013739 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013740 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013741 && app.curAdj == curHiddenAdj) {
13742 step++;
13743 if (step >= factor) {
13744 step = 0;
13745 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013746 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013747 }
13748 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013749 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013750 numHidden++;
13751 if (numHidden > mProcessLimit) {
13752 Slog.i(TAG, "No longer want " + app.processName
13753 + " (pid " + app.pid + "): hidden #" + numHidden);
13754 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13755 app.processName, app.setAdj, "too many background");
13756 app.killedBackground = true;
13757 Process.killProcessQuiet(app.pid);
13758 } else {
13759 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013760 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013761 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013762 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013763 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013764 }
13765 }
13766
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013767 // Now determine the memory trimming level of background processes.
13768 // Unfortunately we need to start at the back of the list to do this
13769 // properly. We only do this if the number of background apps we
13770 // are managing to keep around is less than half the maximum we desire;
13771 // if we are keeping a good number around, we'll let them use whatever
13772 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013773 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013774 final int N = mLruProcesses.size();
13775 factor = numBg/3;
13776 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013777 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013778 for (i=0; i<N; i++) {
13779 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013780 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013781 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13782 try {
13783 app.thread.scheduleTrimMemory(curLevel);
13784 } catch (RemoteException e) {
13785 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013786 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013787 // For these apps we will also finish their activities
13788 // to help them free memory.
13789 mMainStack.destroyActivitiesLocked(app, false);
13790 }
13791 }
13792 app.trimMemoryLevel = curLevel;
13793 step++;
13794 if (step >= factor) {
13795 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013796 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13797 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013798 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013799 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13800 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013801 break;
13802 }
13803 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013804 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013805 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013806 && app.thread != null) {
13807 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013808 app.thread.scheduleTrimMemory(
13809 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013810 } catch (RemoteException e) {
13811 }
13812 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013813 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013814 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013815 && app.pendingUiClean) {
13816 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13817 && app.thread != null) {
13818 try {
13819 app.thread.scheduleTrimMemory(
13820 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13821 } catch (RemoteException e) {
13822 }
13823 }
13824 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13825 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013826 } else {
13827 app.trimMemoryLevel = 0;
13828 }
13829 }
13830 } else {
13831 final int N = mLruProcesses.size();
13832 for (i=0; i<N; i++) {
13833 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013834 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013835 && app.pendingUiClean) {
13836 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13837 && app.thread != null) {
13838 try {
13839 app.thread.scheduleTrimMemory(
13840 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13841 } catch (RemoteException e) {
13842 }
13843 }
13844 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13845 app.pendingUiClean = false;
13846 } else {
13847 app.trimMemoryLevel = 0;
13848 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013849 }
13850 }
13851
13852 if (mAlwaysFinishActivities) {
13853 mMainStack.destroyActivitiesLocked(null, false);
13854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013855 }
13856
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013857 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013858 synchronized (this) {
13859 int i;
13860
13861 // First remove any unused application processes whose package
13862 // has been removed.
13863 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13864 final ProcessRecord app = mRemovedProcesses.get(i);
13865 if (app.activities.size() == 0
13866 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013867 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013868 TAG, "Exiting empty application process "
13869 + app.processName + " ("
13870 + (app.thread != null ? app.thread.asBinder() : null)
13871 + ")\n");
13872 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013873 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13874 app.processName, app.setAdj, "empty");
13875 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013876 } else {
13877 try {
13878 app.thread.scheduleExit();
13879 } catch (Exception e) {
13880 // Ignore exceptions.
13881 }
13882 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013883 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013884 mRemovedProcesses.remove(i);
13885
13886 if (app.persistent) {
13887 if (app.persistent) {
13888 addAppLocked(app.info);
13889 }
13890 }
13891 }
13892 }
13893
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013894 // Now update the oom adj for all processes.
13895 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013896 }
13897 }
13898
13899 /** This method sends the specified signal to each of the persistent apps */
13900 public void signalPersistentProcesses(int sig) throws RemoteException {
13901 if (sig != Process.SIGNAL_USR1) {
13902 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13903 }
13904
13905 synchronized (this) {
13906 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13907 != PackageManager.PERMISSION_GRANTED) {
13908 throw new SecurityException("Requires permission "
13909 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13910 }
13911
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013912 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13913 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013914 if (r.thread != null && r.persistent) {
13915 Process.sendSignal(r.pid, sig);
13916 }
13917 }
13918 }
13919 }
13920
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013921 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13922 if (proc == null || proc == mProfileProc) {
13923 proc = mProfileProc;
13924 path = mProfileFile;
13925 profileType = mProfileType;
13926 clearProfilerLocked();
13927 }
13928 if (proc == null) {
13929 return;
13930 }
13931 try {
13932 proc.thread.profilerControl(false, path, null, profileType);
13933 } catch (RemoteException e) {
13934 throw new IllegalStateException("Process disappeared");
13935 }
13936 }
13937
13938 private void clearProfilerLocked() {
13939 if (mProfileFd != null) {
13940 try {
13941 mProfileFd.close();
13942 } catch (IOException e) {
13943 }
13944 }
13945 mProfileApp = null;
13946 mProfileProc = null;
13947 mProfileFile = null;
13948 mProfileType = 0;
13949 mAutoStopProfiler = false;
13950 }
13951
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013952 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013953 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013954
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013955 try {
13956 synchronized (this) {
13957 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13958 // its own permission.
13959 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13960 != PackageManager.PERMISSION_GRANTED) {
13961 throw new SecurityException("Requires permission "
13962 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013963 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013964
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013965 if (start && fd == null) {
13966 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013967 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013968
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013969 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013970 if (process != null) {
13971 try {
13972 int pid = Integer.parseInt(process);
13973 synchronized (mPidsSelfLocked) {
13974 proc = mPidsSelfLocked.get(pid);
13975 }
13976 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013977 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013978
13979 if (proc == null) {
13980 HashMap<String, SparseArray<ProcessRecord>> all
13981 = mProcessNames.getMap();
13982 SparseArray<ProcessRecord> procs = all.get(process);
13983 if (procs != null && procs.size() > 0) {
13984 proc = procs.valueAt(0);
13985 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013986 }
13987 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013988
13989 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013990 throw new IllegalArgumentException("Unknown process: " + process);
13991 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013992
13993 if (start) {
13994 stopProfilerLocked(null, null, 0);
13995 setProfileApp(proc.info, proc.processName, path, fd, false);
13996 mProfileProc = proc;
13997 mProfileType = profileType;
13998 try {
13999 fd = fd.dup();
14000 } catch (IOException e) {
14001 fd = null;
14002 }
14003 proc.thread.profilerControl(start, path, fd, profileType);
14004 fd = null;
14005 mProfileFd = null;
14006 } else {
14007 stopProfilerLocked(proc, path, profileType);
14008 if (fd != null) {
14009 try {
14010 fd.close();
14011 } catch (IOException e) {
14012 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014013 }
14014 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014015
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014016 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014017 }
14018 } catch (RemoteException e) {
14019 throw new IllegalStateException("Process disappeared");
14020 } finally {
14021 if (fd != null) {
14022 try {
14023 fd.close();
14024 } catch (IOException e) {
14025 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014026 }
14027 }
14028 }
Andy McFadden824c5102010-07-09 16:26:57 -070014029
14030 public boolean dumpHeap(String process, boolean managed,
14031 String path, ParcelFileDescriptor fd) throws RemoteException {
14032
14033 try {
14034 synchronized (this) {
14035 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14036 // its own permission (same as profileControl).
14037 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14038 != PackageManager.PERMISSION_GRANTED) {
14039 throw new SecurityException("Requires permission "
14040 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14041 }
14042
14043 if (fd == null) {
14044 throw new IllegalArgumentException("null fd");
14045 }
14046
14047 ProcessRecord proc = null;
14048 try {
14049 int pid = Integer.parseInt(process);
14050 synchronized (mPidsSelfLocked) {
14051 proc = mPidsSelfLocked.get(pid);
14052 }
14053 } catch (NumberFormatException e) {
14054 }
14055
14056 if (proc == null) {
14057 HashMap<String, SparseArray<ProcessRecord>> all
14058 = mProcessNames.getMap();
14059 SparseArray<ProcessRecord> procs = all.get(process);
14060 if (procs != null && procs.size() > 0) {
14061 proc = procs.valueAt(0);
14062 }
14063 }
14064
14065 if (proc == null || proc.thread == null) {
14066 throw new IllegalArgumentException("Unknown process: " + process);
14067 }
14068
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014069 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14070 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014071 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14072 throw new SecurityException("Process not debuggable: " + proc);
14073 }
14074 }
14075
14076 proc.thread.dumpHeap(managed, path, fd);
14077 fd = null;
14078 return true;
14079 }
14080 } catch (RemoteException e) {
14081 throw new IllegalStateException("Process disappeared");
14082 } finally {
14083 if (fd != null) {
14084 try {
14085 fd.close();
14086 } catch (IOException e) {
14087 }
14088 }
14089 }
14090 }
14091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014092 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14093 public void monitor() {
14094 synchronized (this) { }
14095 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014096
14097 public void onCoreSettingsChange(Bundle settings) {
14098 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14099 ProcessRecord processRecord = mLruProcesses.get(i);
14100 try {
14101 if (processRecord.thread != null) {
14102 processRecord.thread.setCoreSettings(settings);
14103 }
14104 } catch (RemoteException re) {
14105 /* ignore */
14106 }
14107 }
14108 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014109
14110 // Multi-user methods
14111
14112 public boolean switchUser(int userid) {
14113 // TODO
14114 return true;
14115 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014116}