blob: 55fb371d1753fd74076990e4cea91ac2026c58f9 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Dianne Hackborn905577f2011-09-07 18:31:28 -0700109import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800111import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.util.PrintWriterPrinter;
113import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700114import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Gravity;
116import android.view.LayoutInflater;
117import android.view.View;
118import android.view.WindowManager;
119import android.view.WindowManagerPolicy;
120
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700121import java.io.BufferedInputStream;
122import java.io.BufferedOutputStream;
123import java.io.DataInputStream;
124import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import java.io.File;
126import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700127import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700129import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200130import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800131import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132import java.io.PrintWriter;
133import java.lang.IllegalStateException;
134import java.lang.ref.WeakReference;
135import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700136import java.util.Collections;
137import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138import java.util.HashMap;
139import java.util.HashSet;
140import java.util.Iterator;
141import java.util.List;
142import java.util.Locale;
143import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700144import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700145import java.util.concurrent.atomic.AtomicBoolean;
146import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700148public final class ActivityManagerService extends ActivityManagerNative
149 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 static final String TAG = "ActivityManager";
151 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400152 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 static final boolean DEBUG_SWITCH = localLOGV || false;
154 static final boolean DEBUG_TASKS = localLOGV || false;
155 static final boolean DEBUG_PAUSE = localLOGV || false;
156 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
157 static final boolean DEBUG_TRANSITION = localLOGV || false;
158 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700159 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700161 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_VISBILITY = localLOGV || false;
163 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700164 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800165 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700167 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700168 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700169 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700170 static final boolean DEBUG_POWER = localLOGV || false;
171 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 static final boolean VALIDATE_TOKENS = false;
173 static final boolean SHOW_ACTIVITY_START_TIME = true;
174
175 // Control over CPU and battery monitoring.
176 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
177 static final boolean MONITOR_CPU_USAGE = true;
178 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
179 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
180 static final boolean MONITOR_THREAD_CPU_USAGE = false;
181
Dianne Hackborn1655be42009-05-08 14:29:01 -0700182 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700183 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700184
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800185 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 // Maximum number of recent tasks that we can remember.
188 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700189
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700190 // Amount of time after a call to stopAppSwitches() during which we will
191 // prevent further untrusted switches from happening.
192 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193
194 // How long we wait for a launched process to attach to the activity manager
195 // before we decide it's never going to come up for real.
196 static final int PROC_START_TIMEOUT = 10*1000;
197
Jeff Brown3f9dd282011-07-08 20:02:19 -0700198 // How long we wait for a launched process to attach to the activity manager
199 // before we decide it's never going to come up for real, when the process was
200 // started with a wrapper for instrumentation (such as Valgrind) because it
201 // could take much longer than usual.
202 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 // How long to wait after going idle before forcing apps to GC.
205 static final int GC_TIMEOUT = 5*1000;
206
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700207 // The minimum amount of time between successive GC requests for a process.
208 static final int GC_MIN_INTERVAL = 60*1000;
209
Dianne Hackborn287952c2010-09-22 22:34:31 -0700210 // The rate at which we check for apps using excessive power -- 15 mins.
211 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
212
213 // The minimum sample duration we will allow before deciding we have
214 // enough data on wake locks to start killing things.
215 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
216
217 // The minimum sample duration we will allow before deciding we have
218 // enough data on CPU usage to start killing things.
219 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 // How long we allow a receiver to run before giving up on it.
222 static final int BROADCAST_TIMEOUT = 10*1000;
223
224 // How long we wait for a service to finish executing.
225 static final int SERVICE_TIMEOUT = 20*1000;
226
227 // How long a service needs to be running until restarting its process
228 // is no longer considered to be a relaunch of the service.
229 static final int SERVICE_RESTART_DURATION = 5*1000;
230
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700231 // How long a service needs to be running until it will start back at
232 // SERVICE_RESTART_DURATION after being killed.
233 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
234
235 // Multiplying factor to increase restart duration time by, for each time
236 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
237 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
238
239 // The minimum amount of time between restarting services that we allow.
240 // That is, when multiple services are restarting, we won't allow each
241 // to restart less than this amount of time from the last one.
242 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 // Maximum amount of time for there to be no activity on a service before
245 // we consider it non-essential and allow its process to go on the
246 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700247 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248
249 // How long we wait until we timeout on key dispatching.
250 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 // How long we wait until we timeout on key dispatching during instrumentation.
253 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
254
Dan Egnor42471dd2010-01-07 17:25:22 -0800255 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256
257 static final String[] EMPTY_STRING_ARRAY = new String[0];
258
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700259 public ActivityStack mMainStack;
260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700262 * Description of a request to start a new activity, which has been held
263 * due to app switches being disabled.
264 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700265 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700266 ActivityRecord r;
267 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700268 Uri[] grantedUriPermissions;
269 int grantedMode;
270 boolean onlyIfNeeded;
271 }
272
273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
274 = new ArrayList<PendingActivityLaunch>();
275
276 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 * List of all active broadcasts that are to be executed immediately
278 * (without waiting for another broadcast to finish). Currently this only
279 * contains broadcasts to registered receivers, to avoid spinning up
280 * a bunch of processes to execute IntentReceiver components.
281 */
282 final ArrayList<BroadcastRecord> mParallelBroadcasts
283 = new ArrayList<BroadcastRecord>();
284
285 /**
286 * List of all active broadcasts that are to be executed one at a time.
287 * The object at the top of the list is the currently activity broadcasts;
288 * those after it are waiting for the top to finish..
289 */
290 final ArrayList<BroadcastRecord> mOrderedBroadcasts
291 = new ArrayList<BroadcastRecord>();
292
293 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800294 * Historical data of past broadcasts, for debugging.
295 */
296 static final int MAX_BROADCAST_HISTORY = 100;
297 final BroadcastRecord[] mBroadcastHistory
298 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
299
300 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 * Set when we current have a BROADCAST_INTENT_MSG in flight.
302 */
303 boolean mBroadcastsScheduled = false;
304
305 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 * Activity we have told the window manager to have key focus.
307 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700308 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700309 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 * List of intents that were used to start the most recent tasks.
311 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700312 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313
314 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700315 * Process management.
316 */
317 final ProcessList mProcessList = new ProcessList();
318
319 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 * All of the applications we currently have running organized by name.
321 * The keys are strings of the application package name (as
322 * returned by the package manager), and the keys are ApplicationRecord
323 * objects.
324 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700325 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326
327 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700328 * The currently running heavy-weight process, if any.
329 */
330 ProcessRecord mHeavyWeightProcess = null;
331
332 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 * The last time that various processes have crashed.
334 */
335 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
336
337 /**
338 * Set of applications that we consider to be bad, and will reject
339 * incoming broadcasts from (which the user has no control over).
340 * Processes are added to this set when they have crashed twice within
341 * a minimum amount of time; they are removed from it when they are
342 * later restarted (hopefully due to some user action). The value is the
343 * time it was added to the list.
344 */
345 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
346
347 /**
348 * All of the processes we currently have running organized by pid.
349 * The keys are the pid running the application.
350 *
351 * <p>NOTE: This object is protected by its own lock, NOT the global
352 * activity manager lock!
353 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700354 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355
356 /**
357 * All of the processes that have been forced to be foreground. The key
358 * is the pid of the caller who requested it (we hold a death
359 * link on it).
360 */
361 abstract class ForegroundToken implements IBinder.DeathRecipient {
362 int pid;
363 IBinder token;
364 }
365 final SparseArray<ForegroundToken> mForegroundProcesses
366 = new SparseArray<ForegroundToken>();
367
368 /**
369 * List of records for processes that someone had tried to start before the
370 * system was ready. We don't start them at that point, but ensure they
371 * are started by the time booting is complete.
372 */
373 final ArrayList<ProcessRecord> mProcessesOnHold
374 = new ArrayList<ProcessRecord>();
375
376 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 * List of persistent applications that are in the process
378 * of being started.
379 */
380 final ArrayList<ProcessRecord> mPersistentStartingProcesses
381 = new ArrayList<ProcessRecord>();
382
383 /**
384 * Processes that are being forcibly torn down.
385 */
386 final ArrayList<ProcessRecord> mRemovedProcesses
387 = new ArrayList<ProcessRecord>();
388
389 /**
390 * List of running applications, sorted by recent usage.
391 * The first entry in the list is the least recently used.
392 * It contains ApplicationRecord objects. This list does NOT include
393 * any persistent application records (since we never want to exit them).
394 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800395 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 = new ArrayList<ProcessRecord>();
397
398 /**
399 * List of processes that should gc as soon as things are idle.
400 */
401 final ArrayList<ProcessRecord> mProcessesToGc
402 = new ArrayList<ProcessRecord>();
403
404 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800405 * This is the process holding what we currently consider to be
406 * the "home" activity.
407 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700408 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800409
410 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400411 * Packages that the user has asked to have run in screen size
412 * compatibility mode instead of filling the screen.
413 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700414 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400415
416 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 * Set of PendingResultRecord objects that are currently active.
418 */
419 final HashSet mPendingResultRecords = new HashSet();
420
421 /**
422 * Set of IntentSenderRecord objects that are currently active.
423 */
424 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
425 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
426
427 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800428 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700429 * already logged DropBox entries for. Guarded by itself. If
430 * something (rogue user app) forces this over
431 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
432 */
433 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
434 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
435
436 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700437 * Strict Mode background batched logging state.
438 *
439 * The string buffer is guarded by itself, and its lock is also
440 * used to determine if another batched write is already
441 * in-flight.
442 */
443 private final StringBuilder mStrictModeBuffer = new StringBuilder();
444
445 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700446 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
447 */
448 private boolean mPendingBroadcastTimeoutMessage;
449
450 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 * Intent broadcast that we have tried to start, but are
452 * waiting for its application's process to be created. We only
453 * need one (instead of a list) because we always process broadcasts
454 * one at a time, so no others can be started while waiting for this
455 * one.
456 */
457 BroadcastRecord mPendingBroadcast = null;
458
459 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700460 * The receiver index that is pending, to restart the broadcast if needed.
461 */
462 int mPendingBroadcastRecvIndex;
463
464 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 * Keeps track of all IIntentReceivers that have been registered for
466 * broadcasts. Hash keys are the receiver IBinder, hash value is
467 * a ReceiverList.
468 */
469 final HashMap mRegisteredReceivers = new HashMap();
470
471 /**
472 * Resolver for broadcast intents to registered receivers.
473 * Holds BroadcastFilter (subclass of IntentFilter).
474 */
475 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
476 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
477 @Override
478 protected boolean allowFilterResult(
479 BroadcastFilter filter, List<BroadcastFilter> dest) {
480 IBinder target = filter.receiverList.receiver.asBinder();
481 for (int i=dest.size()-1; i>=0; i--) {
482 if (dest.get(i).receiverList.receiver.asBinder() == target) {
483 return false;
484 }
485 }
486 return true;
487 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700488
489 @Override
490 protected String packageForFilter(BroadcastFilter filter) {
491 return filter.packageName;
492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 };
494
495 /**
496 * State of all active sticky broadcasts. Keys are the action of the
497 * sticky Intent, values are an ArrayList of all broadcasted intents with
498 * that action (which should usually be one).
499 */
500 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
501 new HashMap<String, ArrayList<Intent>>();
502
503 /**
504 * All currently running services.
505 */
506 final HashMap<ComponentName, ServiceRecord> mServices =
507 new HashMap<ComponentName, ServiceRecord>();
508
509 /**
510 * All currently running services indexed by the Intent used to start them.
511 */
512 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
513 new HashMap<Intent.FilterComparison, ServiceRecord>();
514
515 /**
516 * All currently bound service connections. Keys are the IBinder of
517 * the client's IServiceConnection.
518 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700519 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
520 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521
522 /**
523 * List of services that we have been asked to start,
524 * but haven't yet been able to. It is used to hold start requests
525 * while waiting for their corresponding application thread to get
526 * going.
527 */
528 final ArrayList<ServiceRecord> mPendingServices
529 = new ArrayList<ServiceRecord>();
530
531 /**
532 * List of services that are scheduled to restart following a crash.
533 */
534 final ArrayList<ServiceRecord> mRestartingServices
535 = new ArrayList<ServiceRecord>();
536
537 /**
538 * List of services that are in the process of being stopped.
539 */
540 final ArrayList<ServiceRecord> mStoppingServices
541 = new ArrayList<ServiceRecord>();
542
543 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700544 * Backup/restore process management
545 */
546 String mBackupAppName = null;
547 BackupRecord mBackupTarget = null;
548
549 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 * List of PendingThumbnailsRecord objects of clients who are still
551 * waiting to receive all of the thumbnails for a task.
552 */
553 final ArrayList mPendingThumbnails = new ArrayList();
554
555 /**
556 * List of HistoryRecord objects that have been finished and must
557 * still report back to a pending thumbnail receiver.
558 */
559 final ArrayList mCancelledThumbnails = new ArrayList();
560
561 /**
562 * All of the currently running global content providers. Keys are a
563 * string containing the provider name and values are a
564 * ContentProviderRecord object containing the data about it. Note
565 * that a single provider may be published under multiple names, so
566 * there may be multiple entries here for a single one in mProvidersByClass.
567 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700568 final HashMap<String, ContentProviderRecord> mProvidersByName
569 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570
571 /**
572 * All of the currently running global content providers. Keys are a
573 * string containing the provider's implementation class and values are a
574 * ContentProviderRecord object containing the data about it.
575 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700576 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
577 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578
579 /**
580 * List of content providers who have clients waiting for them. The
581 * application is currently being launched and the provider will be
582 * removed from this list once it is published.
583 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700584 final ArrayList<ContentProviderRecord> mLaunchingProviders
585 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586
587 /**
588 * Global set of specific Uri permissions that have been granted.
589 */
590 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
591 = new SparseArray<HashMap<Uri, UriPermission>>();
592
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800593 CoreSettingsObserver mCoreSettingsObserver;
594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 /**
596 * Thread-local storage used to carry caller permissions over through
597 * indirect content-provider access.
598 * @see #ActivityManagerService.openContentUri()
599 */
600 private class Identity {
601 public int pid;
602 public int uid;
603
604 Identity(int _pid, int _uid) {
605 pid = _pid;
606 uid = _uid;
607 }
608 }
609 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
610
611 /**
612 * All information we have collected about the runtime performance of
613 * any user id that can impact battery performance.
614 */
615 final BatteryStatsService mBatteryStatsService;
616
617 /**
618 * information about component usage
619 */
620 final UsageStatsService mUsageStatsService;
621
622 /**
623 * Current configuration information. HistoryRecord objects are given
624 * a reference to this object to indicate which configuration they are
625 * currently running in, so this object must be kept immutable.
626 */
627 Configuration mConfiguration = new Configuration();
628
629 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800630 * Current sequencing integer of the configuration, for skipping old
631 * configurations.
632 */
633 int mConfigurationSeq = 0;
634
635 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700636 * Hardware-reported OpenGLES version.
637 */
638 final int GL_ES_VERSION;
639
640 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 * List of initialization arguments to pass to all processes when binding applications to them.
642 * For example, references to the commonly used services.
643 */
644 HashMap<String, IBinder> mAppBindArgs;
645
646 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700647 * Temporary to avoid allocations. Protected by main lock.
648 */
649 final StringBuilder mStringBuilder = new StringBuilder(256);
650
651 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 * Used to control how we initialize the service.
653 */
654 boolean mStartRunning = false;
655 ComponentName mTopComponent;
656 String mTopAction;
657 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700658 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 boolean mSystemReady = false;
660 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700661 boolean mWaitingUpdate = false;
662 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700663 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700664 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665
666 Context mContext;
667
668 int mFactoryTest;
669
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700670 boolean mCheckedForSetup;
671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700673 * The time at which we will allow normal application switches again,
674 * after a call to {@link #stopAppSwitches()}.
675 */
676 long mAppSwitchesAllowedTime;
677
678 /**
679 * This is set to true after the first switch after mAppSwitchesAllowedTime
680 * is set; any switches after that will clear the time.
681 */
682 boolean mDidAppSwitch;
683
684 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700685 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700686 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700687 long mLastPowerCheckRealtime;
688
689 /**
690 * Last time (in uptime) at which we checked for power usage.
691 */
692 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700693
694 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 * Set while we are wanting to sleep, to prevent any
696 * activities from being started/resumed.
697 */
698 boolean mSleeping = false;
699
700 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700701 * Set if we are shutting down the system, similar to sleeping.
702 */
703 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704
705 /**
706 * Task identifier that activities are currently being started
707 * in. Incremented each time a new task is created.
708 * todo: Replace this with a TokenSpace class that generates non-repeating
709 * integers that won't wrap.
710 */
711 int mCurTask = 1;
712
713 /**
714 * Current sequence id for oom_adj computation traversal.
715 */
716 int mAdjSeq = 0;
717
718 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700719 * Current sequence id for process LRU updating.
720 */
721 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722
723 /**
724 * System monitoring: number of processes that died since the last
725 * N procs were started.
726 */
727 int[] mProcDeaths = new int[20];
728
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700729 /**
730 * This is set if we had to do a delayed dexopt of an app before launching
731 * it, to increasing the ANR timeouts in that case.
732 */
733 boolean mDidDexOpt;
734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 String mDebugApp = null;
736 boolean mWaitForDebugger = false;
737 boolean mDebugTransient = false;
738 String mOrigDebugApp = null;
739 boolean mOrigWaitForDebugger = false;
740 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700741 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700742 String mProfileApp = null;
743 ProcessRecord mProfileProc = null;
744 String mProfileFile;
745 ParcelFileDescriptor mProfileFd;
746 int mProfileType = 0;
747 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700749 final RemoteCallbackList<IActivityWatcher> mWatchers
750 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700751
752 final RemoteCallbackList<IProcessObserver> mProcessObservers
753 = new RemoteCallbackList<IProcessObserver>();
754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 /**
756 * Callback of last caller to {@link #requestPss}.
757 */
758 Runnable mRequestPssCallback;
759
760 /**
761 * Remaining processes for which we are waiting results from the last
762 * call to {@link #requestPss}.
763 */
764 final ArrayList<ProcessRecord> mRequestPssList
765 = new ArrayList<ProcessRecord>();
766
767 /**
768 * Runtime statistics collection thread. This object's lock is used to
769 * protect all related state.
770 */
771 final Thread mProcessStatsThread;
772
773 /**
774 * Used to collect process stats when showing not responding dialog.
775 * Protected by mProcessStatsThread.
776 */
777 final ProcessStats mProcessStats = new ProcessStats(
778 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700779 final AtomicLong mLastCpuTime = new AtomicLong(0);
780 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 long mLastWriteTime = 0;
783
784 /**
785 * Set to true after the system has finished booting.
786 */
787 boolean mBooted = false;
788
Dianne Hackborn7d608422011-08-07 16:24:18 -0700789 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700790 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791
792 WindowManagerService mWindowManager;
793
794 static ActivityManagerService mSelf;
795 static ActivityThread mSystemThread;
796
797 private final class AppDeathRecipient implements IBinder.DeathRecipient {
798 final ProcessRecord mApp;
799 final int mPid;
800 final IApplicationThread mAppThread;
801
802 AppDeathRecipient(ProcessRecord app, int pid,
803 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800804 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 TAG, "New death recipient " + this
806 + " for thread " + thread.asBinder());
807 mApp = app;
808 mPid = pid;
809 mAppThread = thread;
810 }
811
812 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800813 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 TAG, "Death received in " + this
815 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 synchronized(ActivityManagerService.this) {
817 appDiedLocked(mApp, mPid, mAppThread);
818 }
819 }
820 }
821
822 static final int SHOW_ERROR_MSG = 1;
823 static final int SHOW_NOT_RESPONDING_MSG = 2;
824 static final int SHOW_FACTORY_ERROR_MSG = 3;
825 static final int UPDATE_CONFIGURATION_MSG = 4;
826 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
827 static final int WAIT_FOR_DEBUGGER_MSG = 6;
828 static final int BROADCAST_INTENT_MSG = 7;
829 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 static final int SERVICE_TIMEOUT_MSG = 12;
831 static final int UPDATE_TIME_ZONE = 13;
832 static final int SHOW_UID_ERROR_MSG = 14;
833 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700835 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700836 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800837 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700838 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
839 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700840 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700841 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700842 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700843 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700844 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700845 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
846 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847
848 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700849 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850
851 final Handler mHandler = new Handler() {
852 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800853 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 //}
855
856 public void handleMessage(Message msg) {
857 switch (msg.what) {
858 case SHOW_ERROR_MSG: {
859 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 synchronized (ActivityManagerService.this) {
861 ProcessRecord proc = (ProcessRecord)data.get("app");
862 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800863 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 return;
865 }
866 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700867 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800868 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 d.show();
870 proc.crashDialog = d;
871 } else {
872 // The device is asleep, so just pretend that the user
873 // saw a crash dialog and hit "force quit".
874 res.set(0);
875 }
876 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700877
878 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 } break;
880 case SHOW_NOT_RESPONDING_MSG: {
881 synchronized (ActivityManagerService.this) {
882 HashMap data = (HashMap) msg.obj;
883 ProcessRecord proc = (ProcessRecord)data.get("app");
884 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800885 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 return;
887 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800888
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700889 Intent intent = new Intent("android.intent.action.ANR");
890 if (!mProcessesReady) {
891 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
892 }
893 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800894 null, null, 0, null, null, null,
895 false, false, MY_PID, Process.SYSTEM_UID);
896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700898 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 d.show();
900 proc.anrDialog = d;
901 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700902
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700903 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700905 case SHOW_STRICT_MODE_VIOLATION_MSG: {
906 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
907 synchronized (ActivityManagerService.this) {
908 ProcessRecord proc = (ProcessRecord) data.get("app");
909 if (proc == null) {
910 Slog.e(TAG, "App not found when showing strict mode dialog.");
911 break;
912 }
913 if (proc.crashDialog != null) {
914 Slog.e(TAG, "App already has strict mode dialog: " + proc);
915 return;
916 }
917 AppErrorResult res = (AppErrorResult) data.get("result");
918 if (!mSleeping && !mShuttingDown) {
919 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
920 d.show();
921 proc.crashDialog = d;
922 } else {
923 // The device is asleep, so just pretend that the user
924 // saw a crash dialog and hit "force quit".
925 res.set(0);
926 }
927 }
928 ensureBootCompleted();
929 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 case SHOW_FACTORY_ERROR_MSG: {
931 Dialog d = new FactoryErrorDialog(
932 mContext, msg.getData().getCharSequence("msg"));
933 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700934 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 } break;
936 case UPDATE_CONFIGURATION_MSG: {
937 final ContentResolver resolver = mContext.getContentResolver();
938 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
939 } break;
940 case GC_BACKGROUND_PROCESSES_MSG: {
941 synchronized (ActivityManagerService.this) {
942 performAppGcsIfAppropriateLocked();
943 }
944 } break;
945 case WAIT_FOR_DEBUGGER_MSG: {
946 synchronized (ActivityManagerService.this) {
947 ProcessRecord app = (ProcessRecord)msg.obj;
948 if (msg.arg1 != 0) {
949 if (!app.waitedForDebugger) {
950 Dialog d = new AppWaitingForDebuggerDialog(
951 ActivityManagerService.this,
952 mContext, app);
953 app.waitDialog = d;
954 app.waitedForDebugger = true;
955 d.show();
956 }
957 } else {
958 if (app.waitDialog != null) {
959 app.waitDialog.dismiss();
960 app.waitDialog = null;
961 }
962 }
963 }
964 } break;
965 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800966 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 TAG, "Received BROADCAST_INTENT_MSG");
968 processNextBroadcast(true);
969 } break;
970 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700971 synchronized (ActivityManagerService.this) {
972 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700976 if (mDidDexOpt) {
977 mDidDexOpt = false;
978 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
979 nmsg.obj = msg.obj;
980 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
981 return;
982 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 serviceTimeout((ProcessRecord)msg.obj);
984 } break;
985 case UPDATE_TIME_ZONE: {
986 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800987 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
988 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 if (r.thread != null) {
990 try {
991 r.thread.updateTimeZone();
992 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800993 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 }
995 }
996 }
997 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700998 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700999 case CLEAR_DNS_CACHE: {
1000 synchronized (ActivityManagerService.this) {
1001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1002 ProcessRecord r = mLruProcesses.get(i);
1003 if (r.thread != null) {
1004 try {
1005 r.thread.clearDnsCache();
1006 } catch (RemoteException ex) {
1007 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1008 }
1009 }
1010 }
1011 }
1012 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001013 case UPDATE_HTTP_PROXY: {
1014 ProxyProperties proxy = (ProxyProperties)msg.obj;
1015 String host = "";
1016 String port = "";
1017 String exclList = "";
1018 if (proxy != null) {
1019 host = proxy.getHost();
1020 port = Integer.toString(proxy.getPort());
1021 exclList = proxy.getExclusionList();
1022 }
1023 synchronized (ActivityManagerService.this) {
1024 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1025 ProcessRecord r = mLruProcesses.get(i);
1026 if (r.thread != null) {
1027 try {
1028 r.thread.setHttpProxy(host, port, exclList);
1029 } catch (RemoteException ex) {
1030 Slog.w(TAG, "Failed to update http proxy for: " +
1031 r.info.processName);
1032 }
1033 }
1034 }
1035 }
1036 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 case SHOW_UID_ERROR_MSG: {
1038 // XXX This is a temporary dialog, no need to localize.
1039 AlertDialog d = new BaseErrorDialog(mContext);
1040 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1041 d.setCancelable(false);
1042 d.setTitle("System UIDs Inconsistent");
1043 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
Christian Mehlmauer7664e202010-07-20 08:46:17 +02001044 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1046 mUidAlert = d;
1047 d.show();
1048 } break;
1049 case IM_FEELING_LUCKY_MSG: {
1050 if (mUidAlert != null) {
1051 mUidAlert.dismiss();
1052 mUidAlert = null;
1053 }
1054 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001056 if (mDidDexOpt) {
1057 mDidDexOpt = false;
1058 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1059 nmsg.obj = msg.obj;
1060 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1061 return;
1062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 ProcessRecord app = (ProcessRecord)msg.obj;
1064 synchronized (ActivityManagerService.this) {
1065 processStartTimedOutLocked(app);
1066 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001067 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001068 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1069 synchronized (ActivityManagerService.this) {
1070 doPendingActivityLaunchesLocked(true);
1071 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001072 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001073 case KILL_APPLICATION_MSG: {
1074 synchronized (ActivityManagerService.this) {
1075 int uid = msg.arg1;
1076 boolean restart = (msg.arg2 == 1);
1077 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001078 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001079 }
1080 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001081 case FINALIZE_PENDING_INTENT_MSG: {
1082 ((PendingIntentRecord)msg.obj).completeFinalize();
1083 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001084 case POST_HEAVY_NOTIFICATION_MSG: {
1085 INotificationManager inm = NotificationManager.getService();
1086 if (inm == null) {
1087 return;
1088 }
1089
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001090 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001091 ProcessRecord process = root.app;
1092 if (process == null) {
1093 return;
1094 }
1095
1096 try {
1097 Context context = mContext.createPackageContext(process.info.packageName, 0);
1098 String text = mContext.getString(R.string.heavy_weight_notification,
1099 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1100 Notification notification = new Notification();
1101 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1102 notification.when = 0;
1103 notification.flags = Notification.FLAG_ONGOING_EVENT;
1104 notification.tickerText = text;
1105 notification.defaults = 0; // please be quiet
1106 notification.sound = null;
1107 notification.vibrate = null;
1108 notification.setLatestEventInfo(context, text,
1109 mContext.getText(R.string.heavy_weight_notification_detail),
1110 PendingIntent.getActivity(mContext, 0, root.intent,
1111 PendingIntent.FLAG_CANCEL_CURRENT));
1112
1113 try {
1114 int[] outId = new int[1];
1115 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1116 notification, outId);
1117 } catch (RuntimeException e) {
1118 Slog.w(ActivityManagerService.TAG,
1119 "Error showing notification for heavy-weight app", e);
1120 } catch (RemoteException e) {
1121 }
1122 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001123 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001124 }
1125 } break;
1126 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1127 INotificationManager inm = NotificationManager.getService();
1128 if (inm == null) {
1129 return;
1130 }
1131 try {
1132 inm.cancelNotification("android",
1133 R.string.heavy_weight_notification);
1134 } catch (RuntimeException e) {
1135 Slog.w(ActivityManagerService.TAG,
1136 "Error canceling notification for service", e);
1137 } catch (RemoteException e) {
1138 }
1139 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001140 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1141 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001142 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001143 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001144 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1145 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001146 }
1147 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001148 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1149 synchronized (ActivityManagerService.this) {
1150 ActivityRecord ar = (ActivityRecord)msg.obj;
1151 if (mCompatModeDialog != null) {
1152 if (mCompatModeDialog.mAppInfo.packageName.equals(
1153 ar.info.applicationInfo.packageName)) {
1154 return;
1155 }
1156 mCompatModeDialog.dismiss();
1157 mCompatModeDialog = null;
1158 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001159 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001160 if (mCompatModePackages.getPackageAskCompatModeLocked(
1161 ar.packageName)) {
1162 int mode = mCompatModePackages.computeCompatModeLocked(
1163 ar.info.applicationInfo);
1164 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1165 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1166 mCompatModeDialog = new CompatModeDialog(
1167 ActivityManagerService.this, mContext,
1168 ar.info.applicationInfo);
1169 mCompatModeDialog.show();
1170 }
1171 }
1172 }
1173 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001174 break;
1175 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001176 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001177 final int pid = msg.arg1;
1178 final int uid = msg.arg2;
1179 final boolean foregroundActivities = (Boolean) msg.obj;
1180 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001181 break;
1182 }
1183 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001184 final int pid = msg.arg1;
1185 final int uid = msg.arg2;
1186 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001187 break;
1188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 }
1190 }
1191 };
1192
1193 public static void setSystemProcess() {
1194 try {
1195 ActivityManagerService m = mSelf;
1196
1197 ServiceManager.addService("activity", m);
1198 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001199 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 if (MONITOR_CPU_USAGE) {
1201 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 ServiceManager.addService("permission", new PermissionController(m));
1204
1205 ApplicationInfo info =
1206 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001207 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001208 mSystemThread.installSystemApplicationInfo(info);
1209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 synchronized (mSelf) {
1211 ProcessRecord app = mSelf.newProcessRecordLocked(
1212 mSystemThread.getApplicationThread(), info,
1213 info.processName);
1214 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001215 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001216 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1218 synchronized (mSelf.mPidsSelfLocked) {
1219 mSelf.mPidsSelfLocked.put(app.pid, app);
1220 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001221 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 }
1223 } catch (PackageManager.NameNotFoundException e) {
1224 throw new RuntimeException(
1225 "Unable to find android system package", e);
1226 }
1227 }
1228
1229 public void setWindowManager(WindowManagerService wm) {
1230 mWindowManager = wm;
1231 }
1232
1233 public static final Context main(int factoryTest) {
1234 AThread thr = new AThread();
1235 thr.start();
1236
1237 synchronized (thr) {
1238 while (thr.mService == null) {
1239 try {
1240 thr.wait();
1241 } catch (InterruptedException e) {
1242 }
1243 }
1244 }
1245
1246 ActivityManagerService m = thr.mService;
1247 mSelf = m;
1248 ActivityThread at = ActivityThread.systemMain();
1249 mSystemThread = at;
1250 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001251 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 m.mContext = context;
1253 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001254 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255
1256 m.mBatteryStatsService.publish(context);
1257 m.mUsageStatsService.publish(context);
1258
1259 synchronized (thr) {
1260 thr.mReady = true;
1261 thr.notifyAll();
1262 }
1263
1264 m.startRunning(null, null, null, null);
1265
1266 return context;
1267 }
1268
1269 public static ActivityManagerService self() {
1270 return mSelf;
1271 }
1272
1273 static class AThread extends Thread {
1274 ActivityManagerService mService;
1275 boolean mReady = false;
1276
1277 public AThread() {
1278 super("ActivityManager");
1279 }
1280
1281 public void run() {
1282 Looper.prepare();
1283
1284 android.os.Process.setThreadPriority(
1285 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001286 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287
1288 ActivityManagerService m = new ActivityManagerService();
1289
1290 synchronized (this) {
1291 mService = m;
1292 notifyAll();
1293 }
1294
1295 synchronized (this) {
1296 while (!mReady) {
1297 try {
1298 wait();
1299 } catch (InterruptedException e) {
1300 }
1301 }
1302 }
1303
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001304 // For debug builds, log event loop stalls to dropbox for analysis.
1305 if (StrictMode.conditionallyEnableDebugLogging()) {
1306 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1307 }
1308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 Looper.loop();
1310 }
1311 }
1312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 static class MemBinder extends Binder {
1314 ActivityManagerService mActivityManagerService;
1315 MemBinder(ActivityManagerService activityManagerService) {
1316 mActivityManagerService = activityManagerService;
1317 }
1318
1319 @Override
1320 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001321 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1322 != PackageManager.PERMISSION_GRANTED) {
1323 pw.println("Permission Denial: can't dump meminfo from from pid="
1324 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1325 + " without permission " + android.Manifest.permission.DUMP);
1326 return;
1327 }
1328
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001329 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 }
1331 }
1332
Chet Haase9c1e23b2011-03-24 10:51:31 -07001333 static class GraphicsBinder extends Binder {
1334 ActivityManagerService mActivityManagerService;
1335 GraphicsBinder(ActivityManagerService activityManagerService) {
1336 mActivityManagerService = activityManagerService;
1337 }
1338
1339 @Override
1340 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001341 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1342 != PackageManager.PERMISSION_GRANTED) {
1343 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1344 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1345 + " without permission " + android.Manifest.permission.DUMP);
1346 return;
1347 }
1348
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001349 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001350 }
1351 }
1352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 static class CpuBinder extends Binder {
1354 ActivityManagerService mActivityManagerService;
1355 CpuBinder(ActivityManagerService activityManagerService) {
1356 mActivityManagerService = activityManagerService;
1357 }
1358
1359 @Override
1360 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001361 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1362 != PackageManager.PERMISSION_GRANTED) {
1363 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1364 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1365 + " without permission " + android.Manifest.permission.DUMP);
1366 return;
1367 }
1368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001370 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1371 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1372 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373 }
1374 }
1375 }
1376
1377 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001378 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 File dataDir = Environment.getDataDirectory();
1381 File systemDir = new File(dataDir, "system");
1382 systemDir.mkdirs();
1383 mBatteryStatsService = new BatteryStatsService(new File(
1384 systemDir, "batterystats.bin").toString());
1385 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001386 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001387 mOnBattery = DEBUG_POWER ? true
1388 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001389 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001391 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001392 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393
Jack Palevichb90d28c2009-07-22 15:35:24 -07001394 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1395 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1396
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001397 mConfiguration.setToDefaults();
1398 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 mProcessStats.init();
1400
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001401 mCompatModePackages = new CompatModePackages(this, systemDir);
1402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 // Add ourself to the Watchdog monitors.
1404 Watchdog.getInstance().addMonitor(this);
1405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 mProcessStatsThread = new Thread("ProcessStats") {
1407 public void run() {
1408 while (true) {
1409 try {
1410 try {
1411 synchronized(this) {
1412 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001413 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001415 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 // + ", write delay=" + nextWriteDelay);
1417 if (nextWriteDelay < nextCpuDelay) {
1418 nextCpuDelay = nextWriteDelay;
1419 }
1420 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001421 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 this.wait(nextCpuDelay);
1423 }
1424 }
1425 } catch (InterruptedException e) {
1426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 updateCpuStatsNow();
1428 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001429 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 }
1431 }
1432 }
1433 };
1434 mProcessStatsThread.start();
1435 }
1436
1437 @Override
1438 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1439 throws RemoteException {
1440 try {
1441 return super.onTransact(code, data, reply, flags);
1442 } catch (RuntimeException e) {
1443 // The activity manager only throws security exceptions, so let's
1444 // log all others.
1445 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001446 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 }
1448 throw e;
1449 }
1450 }
1451
1452 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001453 final long now = SystemClock.uptimeMillis();
1454 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1455 return;
1456 }
1457 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1458 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 mProcessStatsThread.notify();
1460 }
1461 }
1462 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001464 void updateCpuStatsNow() {
1465 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001466 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 final long now = SystemClock.uptimeMillis();
1468 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001471 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1472 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 haveNewCpuStats = true;
1474 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001475 //Slog.i(TAG, mProcessStats.printCurrentState());
1476 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 // + mProcessStats.getTotalCpuPercent() + "%");
1478
Joe Onorato8a9b2202010-02-26 18:56:32 -08001479 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 if ("true".equals(SystemProperties.get("events.cpu"))) {
1481 int user = mProcessStats.getLastUserTime();
1482 int system = mProcessStats.getLastSystemTime();
1483 int iowait = mProcessStats.getLastIoWaitTime();
1484 int irq = mProcessStats.getLastIrqTime();
1485 int softIrq = mProcessStats.getLastSoftIrqTime();
1486 int idle = mProcessStats.getLastIdleTime();
1487
1488 int total = user + system + iowait + irq + softIrq + idle;
1489 if (total == 0) total = 1;
1490
Doug Zongker2bec3d42009-12-04 12:52:44 -08001491 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 ((user+system+iowait+irq+softIrq) * 100) / total,
1493 (user * 100) / total,
1494 (system * 100) / total,
1495 (iowait * 100) / total,
1496 (irq * 100) / total,
1497 (softIrq * 100) / total);
1498 }
1499 }
1500
Amith Yamasanie43530a2009-08-21 13:11:37 -07001501 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001502 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001503 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 synchronized(mPidsSelfLocked) {
1505 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001506 if (mOnBattery) {
1507 int perc = bstats.startAddingCpuLocked();
1508 int totalUTime = 0;
1509 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001510 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001512 ProcessStats.Stats st = mProcessStats.getStats(i);
1513 if (!st.working) {
1514 continue;
1515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001517 int otherUTime = (st.rel_utime*perc)/100;
1518 int otherSTime = (st.rel_stime*perc)/100;
1519 totalUTime += otherUTime;
1520 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 if (pr != null) {
1522 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001523 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1524 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001525 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001526 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001527 } else {
1528 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001529 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001530 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001531 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1532 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001533 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 }
1536 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001537 bstats.finishAddingCpuLocked(perc, totalUTime,
1538 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 }
1540 }
1541 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1544 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001545 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 }
1547 }
1548 }
1549 }
1550
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001551 @Override
1552 public void batteryNeedsCpuUpdate() {
1553 updateCpuStatsNow();
1554 }
1555
1556 @Override
1557 public void batteryPowerChanged(boolean onBattery) {
1558 // When plugging in, update the CPU stats first before changing
1559 // the plug state.
1560 updateCpuStatsNow();
1561 synchronized (this) {
1562 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001563 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001564 }
1565 }
1566 }
1567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 /**
1569 * Initialize the application bind args. These are passed to each
1570 * process when the bindApplication() IPC is sent to the process. They're
1571 * lazily setup to make sure the services are running when they're asked for.
1572 */
1573 private HashMap<String, IBinder> getCommonServicesLocked() {
1574 if (mAppBindArgs == null) {
1575 mAppBindArgs = new HashMap<String, IBinder>();
1576
1577 // Setup the application init args
1578 mAppBindArgs.put("package", ServiceManager.getService("package"));
1579 mAppBindArgs.put("window", ServiceManager.getService("window"));
1580 mAppBindArgs.put(Context.ALARM_SERVICE,
1581 ServiceManager.getService(Context.ALARM_SERVICE));
1582 }
1583 return mAppBindArgs;
1584 }
1585
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001586 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 if (mFocusedActivity != r) {
1588 mFocusedActivity = r;
1589 mWindowManager.setFocusedApp(r, true);
1590 }
1591 }
1592
Dianne Hackborn906497c2010-05-10 15:57:38 -07001593 private final void updateLruProcessInternalLocked(ProcessRecord app,
1594 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001596 int lrui = mLruProcesses.indexOf(app);
1597 if (lrui >= 0) mLruProcesses.remove(lrui);
1598
1599 int i = mLruProcesses.size()-1;
1600 int skipTop = 0;
1601
Dianne Hackborn906497c2010-05-10 15:57:38 -07001602 app.lruSeq = mLruSeq;
1603
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001604 // compute the new weight for this process.
1605 if (updateActivityTime) {
1606 app.lastActivityTime = SystemClock.uptimeMillis();
1607 }
1608 if (app.activities.size() > 0) {
1609 // If this process has activities, we more strongly want to keep
1610 // it around.
1611 app.lruWeight = app.lastActivityTime;
1612 } else if (app.pubProviders.size() > 0) {
1613 // If this process contains content providers, we want to keep
1614 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001615 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001616 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001617 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001618 } else {
1619 // If this process doesn't have activities, we less strongly
1620 // want to keep it around, and generally want to avoid getting
1621 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001622 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001623 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001624 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001625 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001626
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001627 while (i >= 0) {
1628 ProcessRecord p = mLruProcesses.get(i);
1629 // If this app shouldn't be in front of the first N background
1630 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001631 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001632 skipTop--;
1633 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001634 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001635 mLruProcesses.add(i+1, app);
1636 break;
1637 }
1638 i--;
1639 }
1640 if (i < 0) {
1641 mLruProcesses.add(0, app);
1642 }
1643
Dianne Hackborn906497c2010-05-10 15:57:38 -07001644 // If the app is currently using a content provider or service,
1645 // bump those processes as well.
1646 if (app.connections.size() > 0) {
1647 for (ConnectionRecord cr : app.connections) {
1648 if (cr.binding != null && cr.binding.service != null
1649 && cr.binding.service.app != null
1650 && cr.binding.service.app.lruSeq != mLruSeq) {
1651 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1652 updateActivityTime, i+1);
1653 }
1654 }
1655 }
1656 if (app.conProviders.size() > 0) {
1657 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001658 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1659 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001660 updateActivityTime, i+1);
1661 }
1662 }
1663 }
1664
Joe Onorato8a9b2202010-02-26 18:56:32 -08001665 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 if (oomAdj) {
1667 updateOomAdjLocked();
1668 }
1669 }
1670
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001671 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001672 boolean oomAdj, boolean updateActivityTime) {
1673 mLruSeq++;
1674 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1675 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001676
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001677 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 String processName, int uid) {
1679 if (uid == Process.SYSTEM_UID) {
1680 // The system gets to run in any process. If there are multiple
1681 // processes with the same uid, just pick the first (this
1682 // should never happen).
1683 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1684 processName);
1685 return procs != null ? procs.valueAt(0) : null;
1686 }
1687 ProcessRecord proc = mProcessNames.get(processName, uid);
1688 return proc;
1689 }
1690
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001691 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001692 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001693 try {
1694 if (pm.performDexOpt(packageName)) {
1695 mDidDexOpt = true;
1696 }
1697 } catch (RemoteException e) {
1698 }
1699 }
1700
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001701 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001702 int transit = mWindowManager.getPendingAppTransition();
1703 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1704 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1705 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1706 }
1707
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001708 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001710 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1712 // We don't have to do anything more if:
1713 // (1) There is an existing application record; and
1714 // (2) The caller doesn't think it is dead, OR there is no thread
1715 // object attached to it so we know it couldn't have crashed; and
1716 // (3) There is a pid assigned to it, so it is either starting or
1717 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001718 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 + " app=" + app + " knownToBeDead=" + knownToBeDead
1720 + " thread=" + (app != null ? app.thread : null)
1721 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001722 if (app != null && app.pid > 0) {
1723 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001724 // We already have the app running, or are waiting for it to
1725 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001726 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001727 // If this is a new package in the process, add the package to the list
1728 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001729 return app;
1730 } else {
1731 // An application record is attached to a previous process,
1732 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001733 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001734 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001736 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001738 String hostingNameStr = hostingName != null
1739 ? hostingName.flattenToShortString() : null;
1740
1741 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1742 // If we are in the background, then check to see if this process
1743 // is bad. If so, we will just silently fail.
1744 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001745 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1746 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001747 return null;
1748 }
1749 } else {
1750 // When the user is explicitly starting a process, then clear its
1751 // crash count so that we won't make it bad until they see at
1752 // least one crash dialog again, and make the process good again
1753 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001754 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1755 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 mProcessCrashTimes.remove(info.processName, info.uid);
1757 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001758 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001759 info.processName);
1760 mBadProcesses.remove(info.processName, info.uid);
1761 if (app != null) {
1762 app.bad = false;
1763 }
1764 }
1765 }
1766
1767 if (app == null) {
1768 app = newProcessRecordLocked(null, info, processName);
1769 mProcessNames.put(processName, info.uid, app);
1770 } else {
1771 // If this is a new package in the process, add the package to the list
1772 app.addPackage(info.packageName);
1773 }
1774
1775 // If the system is not ready yet, then hold off on starting this
1776 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001777 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001778 && !isAllowedWhileBooting(info)
1779 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 if (!mProcessesOnHold.contains(app)) {
1781 mProcessesOnHold.add(app);
1782 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001783 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 return app;
1785 }
1786
1787 startProcessLocked(app, hostingType, hostingNameStr);
1788 return (app.pid != 0) ? app : null;
1789 }
1790
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001791 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1792 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1793 }
1794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001795 private final void startProcessLocked(ProcessRecord app,
1796 String hostingType, String hostingNameStr) {
1797 if (app.pid > 0 && app.pid != MY_PID) {
1798 synchronized (mPidsSelfLocked) {
1799 mPidsSelfLocked.remove(app.pid);
1800 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1801 }
1802 app.pid = 0;
1803 }
1804
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001805 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1806 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001807 mProcessesOnHold.remove(app);
1808
1809 updateCpuStats();
1810
1811 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1812 mProcDeaths[0] = 0;
1813
1814 try {
1815 int uid = app.info.uid;
1816 int[] gids = null;
1817 try {
1818 gids = mContext.getPackageManager().getPackageGids(
1819 app.info.packageName);
1820 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001821 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 }
1823 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1824 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1825 && mTopComponent != null
1826 && app.processName.equals(mTopComponent.getPackageName())) {
1827 uid = 0;
1828 }
1829 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1830 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1831 uid = 0;
1832 }
1833 }
1834 int debugFlags = 0;
1835 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1836 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001837 // Also turn on CheckJNI for debuggable apps. It's quite
1838 // awkward to turn on otherwise.
1839 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001840 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001841 // Run the app in safe mode if its manifest requests so or the
1842 // system is booted in safe mode.
1843 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1844 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001845 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1846 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1848 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1849 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001850 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1851 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 if ("1".equals(SystemProperties.get("debug.assert"))) {
1854 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1855 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001856
1857 // Start the process. It will either succeed and return a result containing
1858 // the PID of the new process, or else throw a RuntimeException.
1859 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001860 app.processName, uid, uid, gids, debugFlags,
1861 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001863 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1864 synchronized (bs) {
1865 if (bs.isOnBattery()) {
1866 app.batteryStats.incStartsLocked();
1867 }
1868 }
1869
Jeff Brown3f9dd282011-07-08 20:02:19 -07001870 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 app.processName, hostingType,
1872 hostingNameStr != null ? hostingNameStr : "");
1873
1874 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001875 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001876 }
1877
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001878 StringBuilder buf = mStringBuilder;
1879 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001880 buf.append("Start proc ");
1881 buf.append(app.processName);
1882 buf.append(" for ");
1883 buf.append(hostingType);
1884 if (hostingNameStr != null) {
1885 buf.append(" ");
1886 buf.append(hostingNameStr);
1887 }
1888 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001889 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001890 buf.append(" uid=");
1891 buf.append(uid);
1892 buf.append(" gids={");
1893 if (gids != null) {
1894 for (int gi=0; gi<gids.length; gi++) {
1895 if (gi != 0) buf.append(", ");
1896 buf.append(gids[gi]);
1897
1898 }
1899 }
1900 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001901 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001902 app.pid = startResult.pid;
1903 app.usingWrapper = startResult.usingWrapper;
1904 app.removed = false;
1905 synchronized (mPidsSelfLocked) {
1906 this.mPidsSelfLocked.put(startResult.pid, app);
1907 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1908 msg.obj = app;
1909 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1910 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001911 }
1912 } catch (RuntimeException e) {
1913 // XXX do better error recovery.
1914 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001915 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001916 }
1917 }
1918
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001919 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001920 if (resumed) {
1921 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1922 } else {
1923 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1924 }
1925 }
1926
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001927 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001928 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1929 && mTopAction == null) {
1930 // We are running in factory test mode, but unable to find
1931 // the factory test app, so just sit around displaying the
1932 // error message and don't try to start anything.
1933 return false;
1934 }
1935 Intent intent = new Intent(
1936 mTopAction,
1937 mTopData != null ? Uri.parse(mTopData) : null);
1938 intent.setComponent(mTopComponent);
1939 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1940 intent.addCategory(Intent.CATEGORY_HOME);
1941 }
1942 ActivityInfo aInfo =
1943 intent.resolveActivityInfo(mContext.getPackageManager(),
1944 STOCK_PM_FLAGS);
1945 if (aInfo != null) {
1946 intent.setComponent(new ComponentName(
1947 aInfo.applicationInfo.packageName, aInfo.name));
1948 // Don't do this if the home app is currently being
1949 // instrumented.
1950 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1951 aInfo.applicationInfo.uid);
1952 if (app == null || app.instrumentationClass == null) {
1953 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001954 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001955 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001956 }
1957 }
1958
1959
1960 return true;
1961 }
1962
1963 /**
1964 * Starts the "new version setup screen" if appropriate.
1965 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001966 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001967 // Only do this once per boot.
1968 if (mCheckedForSetup) {
1969 return;
1970 }
1971
1972 // We will show this screen if the current one is a different
1973 // version than the last one shown, and we are not running in
1974 // low-level factory test mode.
1975 final ContentResolver resolver = mContext.getContentResolver();
1976 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1977 Settings.Secure.getInt(resolver,
1978 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1979 mCheckedForSetup = true;
1980
1981 // See if we should be showing the platform update setup UI.
1982 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1983 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1984 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1985
1986 // We don't allow third party apps to replace this.
1987 ResolveInfo ri = null;
1988 for (int i=0; ris != null && i<ris.size(); i++) {
1989 if ((ris.get(i).activityInfo.applicationInfo.flags
1990 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1991 ri = ris.get(i);
1992 break;
1993 }
1994 }
1995
1996 if (ri != null) {
1997 String vers = ri.activityInfo.metaData != null
1998 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
1999 : null;
2000 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2001 vers = ri.activityInfo.applicationInfo.metaData.getString(
2002 Intent.METADATA_SETUP_VERSION);
2003 }
2004 String lastVers = Settings.Secure.getString(
2005 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2006 if (vers != null && !vers.equals(lastVers)) {
2007 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2008 intent.setComponent(new ComponentName(
2009 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002010 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002011 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002012 }
2013 }
2014 }
2015 }
2016
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002017 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002018 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002019 }
2020
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002021 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002022 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002023 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2024 }
2025 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002026
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002027 public void setFrontActivityScreenCompatMode(int mode) {
2028 synchronized (this) {
2029 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2030 }
2031 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002032
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002033 public int getPackageScreenCompatMode(String packageName) {
2034 synchronized (this) {
2035 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2036 }
2037 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002038
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002039 public void setPackageScreenCompatMode(String packageName, int mode) {
2040 synchronized (this) {
2041 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002042 }
2043 }
2044
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002045 public boolean getPackageAskScreenCompat(String packageName) {
2046 synchronized (this) {
2047 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2048 }
2049 }
2050
2051 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2052 synchronized (this) {
2053 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2054 }
2055 }
2056
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002057 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002058 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002059
2060 final int identHash = System.identityHashCode(r);
2061 updateUsageStats(r, true);
2062
2063 int i = mWatchers.beginBroadcast();
2064 while (i > 0) {
2065 i--;
2066 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2067 if (w != null) {
2068 try {
2069 w.activityResuming(identHash);
2070 } catch (RemoteException e) {
2071 }
2072 }
2073 }
2074 mWatchers.finishBroadcast();
2075 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002076
Jeff Sharkeya4620792011-05-20 15:29:23 -07002077 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2078 int i = mProcessObservers.beginBroadcast();
2079 while (i > 0) {
2080 i--;
2081 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2082 if (observer != null) {
2083 try {
2084 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2085 } catch (RemoteException e) {
2086 }
2087 }
2088 }
2089 mProcessObservers.finishBroadcast();
2090 }
2091
2092 private void dispatchProcessDied(int pid, int uid) {
2093 int i = mProcessObservers.beginBroadcast();
2094 while (i > 0) {
2095 i--;
2096 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2097 if (observer != null) {
2098 try {
2099 observer.onProcessDied(pid, uid);
2100 } catch (RemoteException e) {
2101 }
2102 }
2103 }
2104 mProcessObservers.finishBroadcast();
2105 }
2106
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002107 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002108 final int N = mPendingActivityLaunches.size();
2109 if (N <= 0) {
2110 return;
2111 }
2112 for (int i=0; i<N; i++) {
2113 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002114 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002115 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2116 doResume && i == (N-1));
2117 }
2118 mPendingActivityLaunches.clear();
2119 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002120
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002121 public final int startActivity(IApplicationThread caller,
2122 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2123 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002124 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2125 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002126 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002127 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002128 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2129 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002130 }
2131
2132 public final WaitResult startActivityAndWait(IApplicationThread caller,
2133 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2134 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002135 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2136 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002137 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002138 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002139 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002140 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2141 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002142 return res;
2143 }
2144
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002145 public final int startActivityWithConfig(IApplicationThread caller,
2146 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2147 int grantedMode, IBinder resultTo,
2148 String resultWho, int requestCode, boolean onlyIfNeeded,
2149 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002150 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002151 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002152 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002153 }
2154
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002155 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002156 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002157 IBinder resultTo, String resultWho, int requestCode,
2158 int flagsMask, int flagsValues) {
2159 // Refuse possible leaked file descriptors
2160 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2161 throw new IllegalArgumentException("File descriptors passed in Intent");
2162 }
2163
2164 IIntentSender sender = intent.getTarget();
2165 if (!(sender instanceof PendingIntentRecord)) {
2166 throw new IllegalArgumentException("Bad PendingIntent object");
2167 }
2168
2169 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002170
2171 synchronized (this) {
2172 // If this is coming from the currently resumed activity, it is
2173 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002174 if (mMainStack.mResumedActivity != null
2175 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002176 Binder.getCallingUid()) {
2177 mAppSwitchesAllowedTime = 0;
2178 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002179 }
2180
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002181 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002182 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2183 }
2184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 public boolean startNextMatchingActivity(IBinder callingActivity,
2186 Intent intent) {
2187 // Refuse possible leaked file descriptors
2188 if (intent != null && intent.hasFileDescriptors() == true) {
2189 throw new IllegalArgumentException("File descriptors passed in Intent");
2190 }
2191
2192 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002193 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2194 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002195 return false;
2196 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002197 if (r.app == null || r.app.thread == null) {
2198 // The caller is not running... d'oh!
2199 return false;
2200 }
2201 intent = new Intent(intent);
2202 // The caller is not allowed to change the data.
2203 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2204 // And we are resetting to find the next component...
2205 intent.setComponent(null);
2206
2207 ActivityInfo aInfo = null;
2208 try {
2209 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002210 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002211 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002212 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213
2214 // Look for the original activity in the list...
2215 final int N = resolves != null ? resolves.size() : 0;
2216 for (int i=0; i<N; i++) {
2217 ResolveInfo rInfo = resolves.get(i);
2218 if (rInfo.activityInfo.packageName.equals(r.packageName)
2219 && rInfo.activityInfo.name.equals(r.info.name)) {
2220 // We found the current one... the next matching is
2221 // after it.
2222 i++;
2223 if (i<N) {
2224 aInfo = resolves.get(i).activityInfo;
2225 }
2226 break;
2227 }
2228 }
2229 } catch (RemoteException e) {
2230 }
2231
2232 if (aInfo == null) {
2233 // Nobody who is next!
2234 return false;
2235 }
2236
2237 intent.setComponent(new ComponentName(
2238 aInfo.applicationInfo.packageName, aInfo.name));
2239 intent.setFlags(intent.getFlags()&~(
2240 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2241 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2242 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2243 Intent.FLAG_ACTIVITY_NEW_TASK));
2244
2245 // Okay now we need to start the new activity, replacing the
2246 // currently running activity. This is a little tricky because
2247 // we want to start the new one as if the current one is finished,
2248 // but not finish the current one first so that there is no flicker.
2249 // And thus...
2250 final boolean wasFinishing = r.finishing;
2251 r.finishing = true;
2252
2253 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002254 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 final String resultWho = r.resultWho;
2256 final int requestCode = r.requestCode;
2257 r.resultTo = null;
2258 if (resultTo != null) {
2259 resultTo.removeResultsLocked(r, resultWho, requestCode);
2260 }
2261
2262 final long origId = Binder.clearCallingIdentity();
2263 // XXX we are not dealing with propagating grantedUriPermissions...
2264 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002265 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002266 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002267 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 Binder.restoreCallingIdentity(origId);
2269
2270 r.finishing = wasFinishing;
2271 if (res != START_SUCCESS) {
2272 return false;
2273 }
2274 return true;
2275 }
2276 }
2277
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002278 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002279 Intent intent, String resolvedType, IBinder resultTo,
2280 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002281
2282 // This is so super not safe, that only the system (or okay root)
2283 // can do it.
2284 final int callingUid = Binder.getCallingUid();
2285 if (callingUid != 0 && callingUid != Process.myUid()) {
2286 throw new SecurityException(
2287 "startActivityInPackage only available to the system");
2288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002289
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002290 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002291 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2292 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002293 }
2294
2295 public final int startActivities(IApplicationThread caller,
2296 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2297 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2298 }
2299
2300 public final int startActivitiesInPackage(int uid,
2301 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2302
2303 // This is so super not safe, that only the system (or okay root)
2304 // can do it.
2305 final int callingUid = Binder.getCallingUid();
2306 if (callingUid != 0 && callingUid != Process.myUid()) {
2307 throw new SecurityException(
2308 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 }
2310
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002311 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 }
2313
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002314 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002316 // Quick case: check if the top-most recent task is the same.
2317 if (N > 0 && mRecentTasks.get(0) == task) {
2318 return;
2319 }
2320 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 for (int i=0; i<N; i++) {
2322 TaskRecord tr = mRecentTasks.get(i);
2323 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2324 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2325 mRecentTasks.remove(i);
2326 i--;
2327 N--;
2328 if (task.intent == null) {
2329 // If the new recent task we are adding is not fully
2330 // specified, then replace it with the existing recent task.
2331 task = tr;
2332 }
2333 }
2334 }
2335 if (N >= MAX_RECENT_TASKS) {
2336 mRecentTasks.remove(N-1);
2337 }
2338 mRecentTasks.add(0, task);
2339 }
2340
2341 public void setRequestedOrientation(IBinder token,
2342 int requestedOrientation) {
2343 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002344 ActivityRecord r = mMainStack.isInStackLocked(token);
2345 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 return;
2347 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 final long origId = Binder.clearCallingIdentity();
2349 mWindowManager.setAppOrientation(r, requestedOrientation);
2350 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002351 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 r.mayFreezeScreenLocked(r.app) ? r : null);
2353 if (config != null) {
2354 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002355 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002356 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357 }
2358 }
2359 Binder.restoreCallingIdentity(origId);
2360 }
2361 }
2362
2363 public int getRequestedOrientation(IBinder token) {
2364 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002365 ActivityRecord r = mMainStack.isInStackLocked(token);
2366 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002369 return mWindowManager.getAppOrientation(r);
2370 }
2371 }
2372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 /**
2374 * This is the internal entry point for handling Activity.finish().
2375 *
2376 * @param token The Binder token referencing the Activity we want to finish.
2377 * @param resultCode Result code, if any, from this Activity.
2378 * @param resultData Result data (Intent), if any, from this Activity.
2379 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002380 * @return Returns true if the activity successfully finished, or false if it is still running.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 */
2382 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2383 // Refuse possible leaked file descriptors
2384 if (resultData != null && resultData.hasFileDescriptors() == true) {
2385 throw new IllegalArgumentException("File descriptors passed in Intent");
2386 }
2387
2388 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002389 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002390 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002391 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002392 if (next != null) {
2393 // ask watcher if this is allowed
2394 boolean resumeOK = true;
2395 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002396 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002397 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002398 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 }
2400
2401 if (!resumeOK) {
2402 return false;
2403 }
2404 }
2405 }
2406 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002407 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002408 resultData, "app-request");
2409 Binder.restoreCallingIdentity(origId);
2410 return res;
2411 }
2412 }
2413
Dianne Hackborn860755f2010-06-03 18:47:52 -07002414 public final void finishHeavyWeightApp() {
2415 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2416 != PackageManager.PERMISSION_GRANTED) {
2417 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2418 + Binder.getCallingPid()
2419 + ", uid=" + Binder.getCallingUid()
2420 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2421 Slog.w(TAG, msg);
2422 throw new SecurityException(msg);
2423 }
2424
2425 synchronized(this) {
2426 if (mHeavyWeightProcess == null) {
2427 return;
2428 }
2429
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002430 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002431 mHeavyWeightProcess.activities);
2432 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002433 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002434 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002435 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002436 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002437 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002438 null, "finish-heavy");
2439 }
2440 }
2441 }
2442
2443 mHeavyWeightProcess = null;
2444 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2445 }
2446 }
2447
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002448 public void crashApplication(int uid, int initialPid, String packageName,
2449 String message) {
2450 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2451 != PackageManager.PERMISSION_GRANTED) {
2452 String msg = "Permission Denial: crashApplication() from pid="
2453 + Binder.getCallingPid()
2454 + ", uid=" + Binder.getCallingUid()
2455 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2456 Slog.w(TAG, msg);
2457 throw new SecurityException(msg);
2458 }
2459
2460 synchronized(this) {
2461 ProcessRecord proc = null;
2462
2463 // Figure out which process to kill. We don't trust that initialPid
2464 // still has any relation to current pids, so must scan through the
2465 // list.
2466 synchronized (mPidsSelfLocked) {
2467 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2468 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2469 if (p.info.uid != uid) {
2470 continue;
2471 }
2472 if (p.pid == initialPid) {
2473 proc = p;
2474 break;
2475 }
2476 for (String str : p.pkgList) {
2477 if (str.equals(packageName)) {
2478 proc = p;
2479 }
2480 }
2481 }
2482 }
2483
2484 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002485 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002486 + " initialPid=" + initialPid
2487 + " packageName=" + packageName);
2488 return;
2489 }
2490
2491 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002492 if (proc.pid == Process.myPid()) {
2493 Log.w(TAG, "crashApplication: trying to crash self!");
2494 return;
2495 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002496 long ident = Binder.clearCallingIdentity();
2497 try {
2498 proc.thread.scheduleCrash(message);
2499 } catch (RemoteException e) {
2500 }
2501 Binder.restoreCallingIdentity(ident);
2502 }
2503 }
2504 }
2505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 public final void finishSubActivity(IBinder token, String resultWho,
2507 int requestCode) {
2508 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002509 ActivityRecord self = mMainStack.isInStackLocked(token);
2510 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002511 return;
2512 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513
2514 final long origId = Binder.clearCallingIdentity();
2515
2516 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002517 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2518 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 if (r.resultTo == self && r.requestCode == requestCode) {
2520 if ((r.resultWho == null && resultWho == null) ||
2521 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002522 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002523 Activity.RESULT_CANCELED, null, "request-sub");
2524 }
2525 }
2526 }
2527
2528 Binder.restoreCallingIdentity(origId);
2529 }
2530 }
2531
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002532 public boolean willActivityBeVisible(IBinder token) {
2533 synchronized(this) {
2534 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002535 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2536 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002537 if (r == token) {
2538 return true;
2539 }
2540 if (r.fullscreen && !r.finishing) {
2541 return false;
2542 }
2543 }
2544 return true;
2545 }
2546 }
2547
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002548 public void overridePendingTransition(IBinder token, String packageName,
2549 int enterAnim, int exitAnim) {
2550 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002551 ActivityRecord self = mMainStack.isInStackLocked(token);
2552 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002553 return;
2554 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002555
2556 final long origId = Binder.clearCallingIdentity();
2557
2558 if (self.state == ActivityState.RESUMED
2559 || self.state == ActivityState.PAUSING) {
2560 mWindowManager.overridePendingAppTransition(packageName,
2561 enterAnim, exitAnim);
2562 }
2563
2564 Binder.restoreCallingIdentity(origId);
2565 }
2566 }
2567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002568 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002569 * Main function for removing an existing process from the activity manager
2570 * as a result of that process going away. Clears out all connections
2571 * to the process.
2572 */
2573 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002574 boolean restarting, boolean allowRestart) {
2575 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002576 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002577 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 }
2579
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002580 if (mProfileProc == app) {
2581 clearProfilerLocked();
2582 }
2583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002584 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002585 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2586 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2587 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002588 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002589 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2590 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 }
2592
2593 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002594 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595
2596 boolean atTop = true;
2597 boolean hasVisibleActivities = false;
2598
2599 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002600 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002601 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 TAG, "Removing app " + app + " from history with " + i + " entries");
2603 while (i > 0) {
2604 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002605 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002606 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002607 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2608 if (r.app == app) {
2609 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002610 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002611 TAG, "Removing this entry! frozen=" + r.haveState
2612 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002613 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002614 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002615 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002616 mWindowManager.removeAppToken(r);
2617 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002618 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002619 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002620 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621
2622 } else {
2623 // We have the current state for this activity, so
2624 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002625 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002626 TAG, "Keeping entry, setting app to null");
2627 if (r.visible) {
2628 hasVisibleActivities = true;
2629 }
2630 r.app = null;
2631 r.nowVisible = false;
2632 if (!r.haveState) {
2633 r.icicle = null;
2634 }
2635 }
2636
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002637 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002638 }
2639 atTop = false;
2640 }
2641
2642 app.activities.clear();
2643
2644 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002645 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002646 + " running instrumentation " + app.instrumentationClass);
2647 Bundle info = new Bundle();
2648 info.putString("shortMsg", "Process crashed.");
2649 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2650 }
2651
2652 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002653 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002654 // If there was nothing to resume, and we are not already
2655 // restarting this process, but there is a visible activity that
2656 // is hosted by the process... then make sure all visible
2657 // activities are running, taking care of restarting this
2658 // process.
2659 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002660 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002661 }
2662 }
2663 }
2664 }
2665
2666 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2667 IBinder threadBinder = thread.asBinder();
2668
2669 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002670 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2671 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002672 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2673 return i;
2674 }
2675 }
2676 return -1;
2677 }
2678
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002679 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002680 IApplicationThread thread) {
2681 if (thread == null) {
2682 return null;
2683 }
2684
2685 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002686 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002687 }
2688
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002689 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002690 IApplicationThread thread) {
2691
2692 mProcDeaths[0]++;
2693
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002694 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2695 synchronized (stats) {
2696 stats.noteProcessDiedLocked(app.info.uid, pid);
2697 }
2698
Magnus Edlund7bb25812010-02-24 15:45:06 +01002699 // Clean up already done if the process has been re-started.
2700 if (app.pid == pid && app.thread != null &&
2701 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002702 if (!app.killedBackground) {
2703 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2704 + ") has died.");
2705 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002706 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002707 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002708 TAG, "Dying app: " + app + ", pid: " + pid
2709 + ", thread: " + thread.asBinder());
2710 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002711 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002712
2713 if (doLowMem) {
2714 // If there are no longer any background processes running,
2715 // and the app that died was not running instrumentation,
2716 // then tell everyone we are now low on memory.
2717 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002718 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2719 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002720 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721 haveBg = true;
2722 break;
2723 }
2724 }
2725
2726 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002727 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002728 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002729 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2730 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002731 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002732 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2733 // The low memory report is overriding any current
2734 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002735 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002736 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002737 rec.lastRequestedGc = 0;
2738 } else {
2739 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002740 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002741 rec.reportLowMemory = true;
2742 rec.lastLowMemory = now;
2743 mProcessesToGc.remove(rec);
2744 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002745 }
2746 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002747 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002748 }
2749 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002750 } else if (app.pid != pid) {
2751 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002752 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002753 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002754 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002755 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002756 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002757 + thread.asBinder());
2758 }
2759 }
2760
Dan Egnor42471dd2010-01-07 17:25:22 -08002761 /**
2762 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002763 * @param clearTraces causes the dump file to be erased prior to the new
2764 * traces being written, if true; when false, the new traces will be
2765 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002766 * @param firstPids of dalvik VM processes to dump stack traces for first
2767 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002768 * @return file containing stack traces, or null if no dump file is configured
2769 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002770 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2771 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002772 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2773 if (tracesPath == null || tracesPath.length() == 0) {
2774 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002775 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002776
2777 File tracesFile = new File(tracesPath);
2778 try {
2779 File tracesDir = tracesFile.getParentFile();
2780 if (!tracesDir.exists()) tracesFile.mkdirs();
2781 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2782
Christopher Tate6ee412d2010-05-28 12:01:56 -07002783 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002784 tracesFile.createNewFile();
2785 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2786 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002787 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002788 return null;
2789 }
2790
2791 // Use a FileObserver to detect when traces finish writing.
2792 // The order of traces is considered important to maintain for legibility.
2793 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2794 public synchronized void onEvent(int event, String path) { notify(); }
2795 };
2796
2797 try {
2798 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002799
2800 // First collect all of the stacks of the most important pids.
2801 try {
2802 int num = firstPids.size();
2803 for (int i = 0; i < num; i++) {
2804 synchronized (observer) {
2805 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2806 observer.wait(200); // Wait for write-close, give up after 200msec
2807 }
2808 }
2809 } catch (InterruptedException e) {
2810 Log.wtf(TAG, e);
2811 }
2812
2813 // Next measure CPU usage.
2814 if (processStats != null) {
2815 processStats.init();
2816 System.gc();
2817 processStats.update();
2818 try {
2819 synchronized (processStats) {
2820 processStats.wait(500); // measure over 1/2 second.
2821 }
2822 } catch (InterruptedException e) {
2823 }
2824 processStats.update();
2825
2826 // We'll take the stack crawls of just the top apps using CPU.
2827 final int N = processStats.countWorkingStats();
2828 int numProcs = 0;
2829 for (int i=0; i<N && numProcs<5; i++) {
2830 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2831 if (lastPids.indexOfKey(stats.pid) >= 0) {
2832 numProcs++;
2833 try {
2834 synchronized (observer) {
2835 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2836 observer.wait(200); // Wait for write-close, give up after 200msec
2837 }
2838 } catch (InterruptedException e) {
2839 Log.wtf(TAG, e);
2840 }
2841
2842 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002843 }
2844 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002845
2846 return tracesFile;
2847
Dan Egnor42471dd2010-01-07 17:25:22 -08002848 } finally {
2849 observer.stopWatching();
2850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 }
2852
Jeff Brown4d94a762010-09-23 11:33:28 -07002853 private final class AppNotResponding implements Runnable {
2854 private final ProcessRecord mApp;
2855 private final String mAnnotation;
2856
2857 public AppNotResponding(ProcessRecord app, String annotation) {
2858 mApp = app;
2859 mAnnotation = annotation;
2860 }
2861
2862 @Override
2863 public void run() {
2864 appNotResponding(mApp, null, null, mAnnotation);
2865 }
2866 }
2867
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002868 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2869 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002870 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2871 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2872
Dianne Hackborn287952c2010-09-22 22:34:31 -07002873 if (mController != null) {
2874 try {
2875 // 0 == continue, -1 = kill process immediately
2876 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2877 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2878 } catch (RemoteException e) {
2879 mController = null;
2880 }
2881 }
2882
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002883 long anrTime = SystemClock.uptimeMillis();
2884 if (MONITOR_CPU_USAGE) {
2885 updateCpuStatsNow();
2886 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002887
2888 synchronized (this) {
2889 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2890 if (mShuttingDown) {
2891 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2892 return;
2893 } else if (app.notResponding) {
2894 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2895 return;
2896 } else if (app.crashing) {
2897 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2898 return;
2899 }
2900
2901 // In case we come through here for the same app before completing
2902 // this one, mark as anring now so we will bail out.
2903 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002904
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002905 // Log the ANR to the event log.
2906 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2907 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002908
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002909 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002910 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002911
2912 int parentPid = app.pid;
2913 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002914 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002915
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002916 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002917
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002918 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2919 ProcessRecord r = mLruProcesses.get(i);
2920 if (r != null && r.thread != null) {
2921 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002922 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2923 if (r.persistent) {
2924 firstPids.add(pid);
2925 } else {
2926 lastPids.put(pid, Boolean.TRUE);
2927 }
2928 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002930 }
2931 }
2932
Dan Egnor42471dd2010-01-07 17:25:22 -08002933 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002934 StringBuilder info = mStringBuilder;
2935 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002936 info.append("ANR in ").append(app.processName);
2937 if (activity != null && activity.shortComponentName != null) {
2938 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002939 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002940 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002941 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002942 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002943 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002944 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002945 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002947
Dianne Hackborn287952c2010-09-22 22:34:31 -07002948 final ProcessStats processStats = new ProcessStats(true);
2949
2950 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2951
Dan Egnor42471dd2010-01-07 17:25:22 -08002952 String cpuInfo = null;
2953 if (MONITOR_CPU_USAGE) {
2954 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002955 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002956 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002957 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002958 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002959 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002960 }
2961
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002962 info.append(processStats.printCurrentState(anrTime));
2963
Joe Onorato8a9b2202010-02-26 18:56:32 -08002964 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002965 if (tracesFile == null) {
2966 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2967 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2968 }
2969
2970 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2971
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002972 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002973 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002974 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2975 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002976 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002977 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2978 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 }
2980 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002981 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002982 }
2983 }
2984
Dan Egnor42471dd2010-01-07 17:25:22 -08002985 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2986 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2987 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002988
2989 synchronized (this) {
2990 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002991 Slog.w(TAG, "Killing " + app + ": background ANR");
2992 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
2993 app.processName, app.setAdj, "background ANR");
2994 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002995 return;
2996 }
2997
2998 // Set the app's notResponding state, and look up the errorReportReceiver
2999 makeAppNotRespondingLocked(app,
3000 activity != null ? activity.shortComponentName : null,
3001 annotation != null ? "ANR " + annotation : "ANR",
3002 info.toString());
3003
3004 // Bring up the infamous App Not Responding dialog
3005 Message msg = Message.obtain();
3006 HashMap map = new HashMap();
3007 msg.what = SHOW_NOT_RESPONDING_MSG;
3008 msg.obj = map;
3009 map.put("app", app);
3010 if (activity != null) {
3011 map.put("activity", activity);
3012 }
3013
3014 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003015 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003016 }
3017
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003018 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3019 if (!mLaunchWarningShown) {
3020 mLaunchWarningShown = true;
3021 mHandler.post(new Runnable() {
3022 @Override
3023 public void run() {
3024 synchronized (ActivityManagerService.this) {
3025 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3026 d.show();
3027 mHandler.postDelayed(new Runnable() {
3028 @Override
3029 public void run() {
3030 synchronized (ActivityManagerService.this) {
3031 d.dismiss();
3032 mLaunchWarningShown = false;
3033 }
3034 }
3035 }, 4000);
3036 }
3037 }
3038 });
3039 }
3040 }
3041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003042 public boolean clearApplicationUserData(final String packageName,
3043 final IPackageDataObserver observer) {
3044 int uid = Binder.getCallingUid();
3045 int pid = Binder.getCallingPid();
3046 long callingId = Binder.clearCallingIdentity();
3047 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003048 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003049 int pkgUid = -1;
3050 synchronized(this) {
3051 try {
3052 pkgUid = pm.getPackageUid(packageName);
3053 } catch (RemoteException e) {
3054 }
3055 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003056 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003057 return false;
3058 }
3059 if (uid == pkgUid || checkComponentPermission(
3060 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003061 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003062 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003063 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003064 } else {
3065 throw new SecurityException(pid+" does not have permission:"+
3066 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3067 "for process:"+packageName);
3068 }
3069 }
3070
3071 try {
3072 //clear application user data
3073 pm.clearApplicationUserData(packageName, observer);
3074 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3075 Uri.fromParts("package", packageName, null));
3076 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003077 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3078 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003079 } catch (RemoteException e) {
3080 }
3081 } finally {
3082 Binder.restoreCallingIdentity(callingId);
3083 }
3084 return true;
3085 }
3086
Dianne Hackborn03abb812010-01-04 18:43:19 -08003087 public void killBackgroundProcesses(final String packageName) {
3088 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3089 != PackageManager.PERMISSION_GRANTED &&
3090 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3091 != PackageManager.PERMISSION_GRANTED) {
3092 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003093 + Binder.getCallingPid()
3094 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003095 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003096 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003097 throw new SecurityException(msg);
3098 }
3099
3100 long callingId = Binder.clearCallingIdentity();
3101 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003102 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003103 int pkgUid = -1;
3104 synchronized(this) {
3105 try {
3106 pkgUid = pm.getPackageUid(packageName);
3107 } catch (RemoteException e) {
3108 }
3109 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003110 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003111 return;
3112 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003113 killPackageProcessesLocked(packageName, pkgUid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003114 ProcessList.SECONDARY_SERVER_ADJ, false, true, true, false);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003115 }
3116 } finally {
3117 Binder.restoreCallingIdentity(callingId);
3118 }
3119 }
3120
3121 public void forceStopPackage(final String packageName) {
3122 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3123 != PackageManager.PERMISSION_GRANTED) {
3124 String msg = "Permission Denial: forceStopPackage() from pid="
3125 + Binder.getCallingPid()
3126 + ", uid=" + Binder.getCallingUid()
3127 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003128 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003129 throw new SecurityException(msg);
3130 }
3131
3132 long callingId = Binder.clearCallingIdentity();
3133 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003134 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003135 int pkgUid = -1;
3136 synchronized(this) {
3137 try {
3138 pkgUid = pm.getPackageUid(packageName);
3139 } catch (RemoteException e) {
3140 }
3141 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003142 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003143 return;
3144 }
3145 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003146 try {
3147 pm.setPackageStoppedState(packageName, true);
3148 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003149 } catch (IllegalArgumentException e) {
3150 Slog.w(TAG, "Failed trying to unstop package "
3151 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003152 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003153 }
3154 } finally {
3155 Binder.restoreCallingIdentity(callingId);
3156 }
3157 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003158
3159 /*
3160 * The pkg name and uid have to be specified.
3161 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3162 */
3163 public void killApplicationWithUid(String pkg, int uid) {
3164 if (pkg == null) {
3165 return;
3166 }
3167 // Make sure the uid is valid.
3168 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003169 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003170 return;
3171 }
3172 int callerUid = Binder.getCallingUid();
3173 // Only the system server can kill an application
3174 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003175 // Post an aysnc message to kill the application
3176 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3177 msg.arg1 = uid;
3178 msg.arg2 = 0;
3179 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003180 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003181 } else {
3182 throw new SecurityException(callerUid + " cannot kill pkg: " +
3183 pkg);
3184 }
3185 }
3186
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003187 public void closeSystemDialogs(String reason) {
3188 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003189 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003190 if (reason != null) {
3191 intent.putExtra("reason", reason);
3192 }
3193
3194 final int uid = Binder.getCallingUid();
3195 final long origId = Binder.clearCallingIdentity();
3196 synchronized (this) {
3197 int i = mWatchers.beginBroadcast();
3198 while (i > 0) {
3199 i--;
3200 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3201 if (w != null) {
3202 try {
3203 w.closingSystemDialogs(reason);
3204 } catch (RemoteException e) {
3205 }
3206 }
3207 }
3208 mWatchers.finishBroadcast();
3209
Dianne Hackbornffa42482009-09-23 22:20:11 -07003210 mWindowManager.closeSystemDialogs(reason);
3211
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003212 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3213 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003214 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003215 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003216 Activity.RESULT_CANCELED, null, "close-sys");
3217 }
3218 }
3219
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003220 broadcastIntentLocked(null, null, intent, null,
3221 null, 0, null, null, null, false, false, -1, uid);
3222 }
3223 Binder.restoreCallingIdentity(origId);
3224 }
3225
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003226 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003227 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003228 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3229 for (int i=pids.length-1; i>=0; i--) {
3230 infos[i] = new Debug.MemoryInfo();
3231 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003232 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003233 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003234 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003235
Dianne Hackbornb437e092011-08-05 17:50:29 -07003236 public long[] getProcessPss(int[] pids) throws RemoteException {
3237 long[] pss = new long[pids.length];
3238 for (int i=pids.length-1; i>=0; i--) {
3239 pss[i] = Debug.getPss(pids[i]);
3240 }
3241 return pss;
3242 }
3243
Christopher Tate5e1ab332009-09-01 20:32:49 -07003244 public void killApplicationProcess(String processName, int uid) {
3245 if (processName == null) {
3246 return;
3247 }
3248
3249 int callerUid = Binder.getCallingUid();
3250 // Only the system server can kill an application
3251 if (callerUid == Process.SYSTEM_UID) {
3252 synchronized (this) {
3253 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003254 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003255 try {
3256 app.thread.scheduleSuicide();
3257 } catch (RemoteException e) {
3258 // If the other end already died, then our work here is done.
3259 }
3260 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003261 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003262 + processName + " / " + uid);
3263 }
3264 }
3265 } else {
3266 throw new SecurityException(callerUid + " cannot kill app process: " +
3267 processName);
3268 }
3269 }
3270
Dianne Hackborn03abb812010-01-04 18:43:19 -08003271 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003272 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003273 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3274 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003275 if (!mProcessesReady) {
3276 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3277 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003278 intent.putExtra(Intent.EXTRA_UID, uid);
3279 broadcastIntentLocked(null, null, intent,
3280 null, null, 0, null, null, null,
3281 false, false, MY_PID, Process.SYSTEM_UID);
3282 }
3283
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003284 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003285 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3286 boolean evenPersistent) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003287 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003288
Dianne Hackborn03abb812010-01-04 18:43:19 -08003289 // Remove all processes this package may have touched: all with the
3290 // same UID (except for the system or root user), and all whose name
3291 // matches the package name.
3292 final String procNamePrefix = packageName + ":";
3293 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3294 final int NA = apps.size();
3295 for (int ia=0; ia<NA; ia++) {
3296 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003297 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003298 // we don't kill persistent processes
3299 continue;
3300 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003301 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003302 if (doit) {
3303 procs.add(app);
3304 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003305 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3306 || app.processName.equals(packageName)
3307 || app.processName.startsWith(procNamePrefix)) {
3308 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003309 if (!doit) {
3310 return true;
3311 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003312 app.removed = true;
3313 procs.add(app);
3314 }
3315 }
3316 }
3317 }
3318
3319 int N = procs.size();
3320 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003321 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003322 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003323 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003324 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003325
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003326 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003327 boolean callerWillRestart, boolean purgeCache, boolean doit,
3328 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003329 int i;
3330 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003332 if (uid < 0) {
3333 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003334 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003335 } catch (RemoteException e) {
3336 }
3337 }
3338
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003339 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003340 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003341
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003342 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3343 while (badApps.hasNext()) {
3344 SparseArray<Long> ba = badApps.next();
3345 if (ba.get(uid) != null) {
3346 badApps.remove();
3347 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003348 }
3349 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003350
3351 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Christopher Tate3dacd842011-08-19 14:56:15 -07003352 callerWillRestart, false, doit, evenPersistent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003354 TaskRecord lastTask = null;
3355 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003356 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003357 final boolean samePackage = r.packageName.equals(name);
3358 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003359 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003360 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003361 if (r.finishing) {
3362 // If this activity is just finishing, then it is not
3363 // interesting as far as something to stop.
3364 continue;
3365 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003366 return true;
3367 }
3368 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003369 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003370 if (samePackage) {
3371 if (r.app != null) {
3372 r.app.removed = true;
3373 }
3374 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003375 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003376 lastTask = r.task;
3377 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3378 null, "force-stop")) {
3379 i--;
3380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 }
3382 }
3383
3384 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3385 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003386 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003387 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003388 if (!doit) {
3389 return true;
3390 }
3391 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003392 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 if (service.app != null) {
3394 service.app.removed = true;
3395 }
3396 service.app = null;
3397 services.add(service);
3398 }
3399 }
3400
3401 N = services.size();
3402 for (i=0; i<N; i++) {
3403 bringDownServiceLocked(services.get(i), true);
3404 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003405
3406 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3407 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3408 if (provider.info.packageName.equals(name)
3409 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3410 if (!doit) {
3411 return true;
3412 }
3413 didSomething = true;
3414 providers.add(provider);
3415 }
3416 }
3417
3418 N = providers.size();
3419 for (i=0; i<N; i++) {
3420 removeDyingProviderLocked(null, providers.get(i));
3421 }
3422
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003423 if (doit) {
3424 if (purgeCache) {
3425 AttributeCache ac = AttributeCache.instance();
3426 if (ac != null) {
3427 ac.removePackage(name);
3428 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003429 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003430 if (mBooted) {
3431 mMainStack.resumeTopActivityLocked(null);
3432 mMainStack.scheduleIdleLocked();
3433 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003434 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003435
3436 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003437 }
3438
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003439 private final boolean removeProcessLocked(ProcessRecord app,
3440 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003441 final String name = app.processName;
3442 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003443 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003444 TAG, "Force removing process " + app + " (" + name
3445 + "/" + uid + ")");
3446
3447 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003448 if (mHeavyWeightProcess == app) {
3449 mHeavyWeightProcess = null;
3450 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003452 boolean needRestart = false;
3453 if (app.pid > 0 && app.pid != MY_PID) {
3454 int pid = app.pid;
3455 synchronized (mPidsSelfLocked) {
3456 mPidsSelfLocked.remove(pid);
3457 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3458 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003459 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003460 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003461 Process.killProcess(pid);
3462
3463 if (app.persistent) {
3464 if (!callerWillRestart) {
3465 addAppLocked(app.info);
3466 } else {
3467 needRestart = true;
3468 }
3469 }
3470 } else {
3471 mRemovedProcesses.add(app);
3472 }
3473
3474 return needRestart;
3475 }
3476
3477 private final void processStartTimedOutLocked(ProcessRecord app) {
3478 final int pid = app.pid;
3479 boolean gone = false;
3480 synchronized (mPidsSelfLocked) {
3481 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3482 if (knownApp != null && knownApp.thread == null) {
3483 mPidsSelfLocked.remove(pid);
3484 gone = true;
3485 }
3486 }
3487
3488 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003489 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003490 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003491 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003492 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003493 if (mHeavyWeightProcess == app) {
3494 mHeavyWeightProcess = null;
3495 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3496 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003497 // Take care of any launching providers waiting for this process.
3498 checkAppInLaunchingProvidersLocked(app, true);
3499 // Take care of any services that are waiting for the process.
3500 for (int i=0; i<mPendingServices.size(); i++) {
3501 ServiceRecord sr = mPendingServices.get(i);
3502 if (app.info.uid == sr.appInfo.uid
3503 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003504 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003505 mPendingServices.remove(i);
3506 i--;
3507 bringDownServiceLocked(sr, true);
3508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003509 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003510 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3511 app.processName, app.setAdj, "start timeout");
3512 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003513 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003514 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003515 try {
3516 IBackupManager bm = IBackupManager.Stub.asInterface(
3517 ServiceManager.getService(Context.BACKUP_SERVICE));
3518 bm.agentDisconnected(app.info.packageName);
3519 } catch (RemoteException e) {
3520 // Can't happen; the backup manager is local
3521 }
3522 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003523 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003524 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003525 mPendingBroadcast.state = BroadcastRecord.IDLE;
3526 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003527 mPendingBroadcast = null;
3528 scheduleBroadcastsLocked();
3529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003530 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003531 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003532 }
3533 }
3534
3535 private final boolean attachApplicationLocked(IApplicationThread thread,
3536 int pid) {
3537
3538 // Find the application record that is being attached... either via
3539 // the pid if we are running in multiple processes, or just pull the
3540 // next app record if we are emulating process with anonymous threads.
3541 ProcessRecord app;
3542 if (pid != MY_PID && pid >= 0) {
3543 synchronized (mPidsSelfLocked) {
3544 app = mPidsSelfLocked.get(pid);
3545 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003546 } else {
3547 app = null;
3548 }
3549
3550 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003551 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003552 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003553 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003555 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003556 } else {
3557 try {
3558 thread.scheduleExit();
3559 } catch (Exception e) {
3560 // Ignore exceptions.
3561 }
3562 }
3563 return false;
3564 }
3565
3566 // If this application record is still attached to a previous
3567 // process, clean it up now.
3568 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003569 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003570 }
3571
3572 // Tell the process all about itself.
3573
Joe Onorato8a9b2202010-02-26 18:56:32 -08003574 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003575 TAG, "Binding process pid " + pid + " to record " + app);
3576
3577 String processName = app.processName;
3578 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003579 AppDeathRecipient adr = new AppDeathRecipient(
3580 app, pid, thread);
3581 thread.asBinder().linkToDeath(adr, 0);
3582 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003583 } catch (RemoteException e) {
3584 app.resetPackageList();
3585 startProcessLocked(app, "link fail", processName);
3586 return false;
3587 }
3588
Doug Zongker2bec3d42009-12-04 12:52:44 -08003589 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003590
3591 app.thread = thread;
3592 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003593 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3594 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003595 app.forcingToForeground = null;
3596 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003597 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 app.debugging = false;
3599
3600 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3601
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003602 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003603 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003604
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003605 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003606 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003607 }
3608
Joe Onorato8a9b2202010-02-26 18:56:32 -08003609 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610 TAG, "New app record " + app
3611 + " thread=" + thread.asBinder() + " pid=" + pid);
3612 try {
3613 int testMode = IApplicationThread.DEBUG_OFF;
3614 if (mDebugApp != null && mDebugApp.equals(processName)) {
3615 testMode = mWaitForDebugger
3616 ? IApplicationThread.DEBUG_WAIT
3617 : IApplicationThread.DEBUG_ON;
3618 app.debugging = true;
3619 if (mDebugTransient) {
3620 mDebugApp = mOrigDebugApp;
3621 mWaitForDebugger = mOrigWaitForDebugger;
3622 }
3623 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003624 String profileFile = app.instrumentationProfileFile;
3625 ParcelFileDescriptor profileFd = null;
3626 boolean profileAutoStop = false;
3627 if (mProfileApp != null && mProfileApp.equals(processName)) {
3628 mProfileProc = app;
3629 profileFile = mProfileFile;
3630 profileFd = mProfileFd;
3631 profileAutoStop = mAutoStopProfiler;
3632 }
3633
Christopher Tate181fafa2009-05-14 11:12:14 -07003634 // If the app is being launched for restore or full backup, set it up specially
3635 boolean isRestrictedBackupMode = false;
3636 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3637 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003638 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003639 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3640 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003641
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003642 ensurePackageDexOpt(app.instrumentationInfo != null
3643 ? app.instrumentationInfo.packageName
3644 : app.info.packageName);
3645 if (app.instrumentationClass != null) {
3646 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003647 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003648 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003649 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003650 ApplicationInfo appInfo = app.instrumentationInfo != null
3651 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003652 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003653 if (profileFd != null) {
3654 profileFd = profileFd.dup();
3655 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003656 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003657 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003659 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003660 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003661 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003662 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003663 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003664 } catch (Exception e) {
3665 // todo: Yikes! What should we do? For now we will try to
3666 // start another process, but that could easily get us in
3667 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003668 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669
3670 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003671 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003672 startProcessLocked(app, "bind fail", processName);
3673 return false;
3674 }
3675
3676 // Remove this record from the list of starting applications.
3677 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003678 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3679 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 mProcessesOnHold.remove(app);
3681
3682 boolean badApp = false;
3683 boolean didSomething = false;
3684
3685 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003686 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003687 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003688 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3689 && processName.equals(hr.processName)) {
3690 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003691 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692 didSomething = true;
3693 }
3694 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003695 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003696 + hr.intent.getComponent().flattenToShortString(), e);
3697 badApp = true;
3698 }
3699 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003700 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003701 }
3702 }
3703
3704 // Find any services that should be running in this process...
3705 if (!badApp && mPendingServices.size() > 0) {
3706 ServiceRecord sr = null;
3707 try {
3708 for (int i=0; i<mPendingServices.size(); i++) {
3709 sr = mPendingServices.get(i);
3710 if (app.info.uid != sr.appInfo.uid
3711 || !processName.equals(sr.processName)) {
3712 continue;
3713 }
3714
3715 mPendingServices.remove(i);
3716 i--;
3717 realStartServiceLocked(sr, app);
3718 didSomething = true;
3719 }
3720 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003721 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003722 + sr.shortName, e);
3723 badApp = true;
3724 }
3725 }
3726
3727 // Check if the next broadcast receiver is in this process...
3728 BroadcastRecord br = mPendingBroadcast;
3729 if (!badApp && br != null && br.curApp == app) {
3730 try {
3731 mPendingBroadcast = null;
3732 processCurBroadcastLocked(br, app);
3733 didSomething = true;
3734 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003735 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003736 + br.curComponent.flattenToShortString(), e);
3737 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003738 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003739 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3740 br.resultExtras, br.resultAbort, true);
3741 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003742 // We need to reset the state if we fails to start the receiver.
3743 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 }
3745 }
3746
Christopher Tate181fafa2009-05-14 11:12:14 -07003747 // Check whether the next backup agent is in this process...
3748 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003749 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003750 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003751 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003752 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3753 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3754 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003755 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003756 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003757 e.printStackTrace();
3758 }
3759 }
3760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003761 if (badApp) {
3762 // todo: Also need to kill application to deal with all
3763 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003764 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003765 return false;
3766 }
3767
3768 if (!didSomething) {
3769 updateOomAdjLocked();
3770 }
3771
3772 return true;
3773 }
3774
3775 public final void attachApplication(IApplicationThread thread) {
3776 synchronized (this) {
3777 int callingPid = Binder.getCallingPid();
3778 final long origId = Binder.clearCallingIdentity();
3779 attachApplicationLocked(thread, callingPid);
3780 Binder.restoreCallingIdentity(origId);
3781 }
3782 }
3783
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003784 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003785 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003786 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3787 if (stopProfiling) {
3788 synchronized (this) {
3789 if (mProfileProc == r.app) {
3790 if (mProfileFd != null) {
3791 try {
3792 mProfileFd.close();
3793 } catch (IOException e) {
3794 }
3795 clearProfilerLocked();
3796 }
3797 }
3798 }
3799 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003800 Binder.restoreCallingIdentity(origId);
3801 }
3802
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003803 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003804 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003805 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003806 mWindowManager.enableScreenAfterBoot();
3807 }
3808
Dianne Hackborn661cd522011-08-22 00:26:20 -07003809 public void showBootMessage(final CharSequence msg, final boolean always) {
3810 mWindowManager.showBootMessage(msg, always);
3811 }
3812
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003813 public void dismissKeyguardOnNextActivity() {
3814 synchronized (this) {
3815 mMainStack.dismissKeyguardOnNextActivityLocked();
3816 }
3817 }
3818
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003819 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003820 IntentFilter pkgFilter = new IntentFilter();
3821 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3822 pkgFilter.addDataScheme("package");
3823 mContext.registerReceiver(new BroadcastReceiver() {
3824 @Override
3825 public void onReceive(Context context, Intent intent) {
3826 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3827 if (pkgs != null) {
3828 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003829 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003830 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003831 setResultCode(Activity.RESULT_OK);
3832 return;
3833 }
3834 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003835 }
3836 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003837 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003838 }, pkgFilter);
3839
3840 synchronized (this) {
3841 // Ensure that any processes we had put on hold are now started
3842 // up.
3843 final int NP = mProcessesOnHold.size();
3844 if (NP > 0) {
3845 ArrayList<ProcessRecord> procs =
3846 new ArrayList<ProcessRecord>(mProcessesOnHold);
3847 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003848 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3849 + procs.get(ip));
3850 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003851 }
3852 }
3853
3854 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003855 // Start looking for apps that are abusing wake locks.
3856 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003857 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003858 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003859 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003860 broadcastIntentLocked(null, null,
3861 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3862 null, null, 0, null, null,
3863 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3864 false, false, MY_PID, Process.SYSTEM_UID);
3865 }
3866 }
3867 }
3868
3869 final void ensureBootCompleted() {
3870 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003871 boolean enableScreen;
3872 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003873 booting = mBooting;
3874 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003875 enableScreen = !mBooted;
3876 mBooted = true;
3877 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003878
3879 if (booting) {
3880 finishBooting();
3881 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003882
3883 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003884 enableScreenAfterBoot();
3885 }
3886 }
3887
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003888 public final void activityPaused(IBinder token) {
3889 final long origId = Binder.clearCallingIdentity();
3890 mMainStack.activityPaused(token, false);
3891 Binder.restoreCallingIdentity(origId);
3892 }
3893
3894 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3895 CharSequence description) {
3896 if (localLOGV) Slog.v(
3897 TAG, "Activity stopped: token=" + token);
3898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003899 // Refuse possible leaked file descriptors
3900 if (icicle != null && icicle.hasFileDescriptors()) {
3901 throw new IllegalArgumentException("File descriptors passed in Bundle");
3902 }
3903
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003904 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905
3906 final long origId = Binder.clearCallingIdentity();
3907
3908 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003909 r = mMainStack.isInStackLocked(token);
3910 if (r != null) {
3911 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003912 }
3913 }
3914
3915 if (r != null) {
3916 sendPendingThumbnail(r, null, null, null, false);
3917 }
3918
3919 trimApplications();
3920
3921 Binder.restoreCallingIdentity(origId);
3922 }
3923
3924 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003925 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003926 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003927 }
3928
3929 public String getCallingPackage(IBinder token) {
3930 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003931 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003932 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003933 }
3934 }
3935
3936 public ComponentName getCallingActivity(IBinder token) {
3937 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003938 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003939 return r != null ? r.intent.getComponent() : null;
3940 }
3941 }
3942
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003943 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003944 ActivityRecord r = mMainStack.isInStackLocked(token);
3945 if (r == null) {
3946 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003947 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003948 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 }
3950
3951 public ComponentName getActivityClassForToken(IBinder token) {
3952 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003953 ActivityRecord r = mMainStack.isInStackLocked(token);
3954 if (r == null) {
3955 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003956 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003957 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 }
3959 }
3960
3961 public String getPackageForToken(IBinder token) {
3962 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003963 ActivityRecord r = mMainStack.isInStackLocked(token);
3964 if (r == null) {
3965 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003966 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003967 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 }
3969 }
3970
3971 public IIntentSender getIntentSender(int type,
3972 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003973 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003974 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003975 if (intents != null) {
3976 if (intents.length < 1) {
3977 throw new IllegalArgumentException("Intents array length must be >= 1");
3978 }
3979 for (int i=0; i<intents.length; i++) {
3980 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003981 if (intent != null) {
3982 if (intent.hasFileDescriptors()) {
3983 throw new IllegalArgumentException("File descriptors passed in Intent");
3984 }
3985 if (type == INTENT_SENDER_BROADCAST &&
3986 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3987 throw new IllegalArgumentException(
3988 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3989 }
3990 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003991 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003992 }
3993 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003994 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003995 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003996 }
3997 }
3998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003999 synchronized(this) {
4000 int callingUid = Binder.getCallingUid();
4001 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004002 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004003 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004004 .getPackageUid(packageName);
4005 if (uid != Binder.getCallingUid()) {
4006 String msg = "Permission Denial: getIntentSender() from pid="
4007 + Binder.getCallingPid()
4008 + ", uid=" + Binder.getCallingUid()
4009 + ", (need uid=" + uid + ")"
4010 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004011 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004012 throw new SecurityException(msg);
4013 }
4014 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004015
4016 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004017 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004019 } catch (RemoteException e) {
4020 throw new SecurityException(e);
4021 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004022 }
4023 }
4024
4025 IIntentSender getIntentSenderLocked(int type,
4026 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004027 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004028 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004029 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004030 activity = mMainStack.isInStackLocked(token);
4031 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004032 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004033 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004034 if (activity.finishing) {
4035 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004036 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004037 }
4038
4039 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4040 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4041 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4042 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4043 |PendingIntent.FLAG_UPDATE_CURRENT);
4044
4045 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4046 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004047 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004048 WeakReference<PendingIntentRecord> ref;
4049 ref = mIntentSenderRecords.get(key);
4050 PendingIntentRecord rec = ref != null ? ref.get() : null;
4051 if (rec != null) {
4052 if (!cancelCurrent) {
4053 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004054 if (rec.key.requestIntent != null) {
4055 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4056 }
4057 if (intents != null) {
4058 intents[intents.length-1] = rec.key.requestIntent;
4059 rec.key.allIntents = intents;
4060 rec.key.allResolvedTypes = resolvedTypes;
4061 } else {
4062 rec.key.allIntents = null;
4063 rec.key.allResolvedTypes = null;
4064 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004065 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004066 return rec;
4067 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004068 rec.canceled = true;
4069 mIntentSenderRecords.remove(key);
4070 }
4071 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004072 return rec;
4073 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004074 rec = new PendingIntentRecord(this, key, callingUid);
4075 mIntentSenderRecords.put(key, rec.ref);
4076 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4077 if (activity.pendingResults == null) {
4078 activity.pendingResults
4079 = new HashSet<WeakReference<PendingIntentRecord>>();
4080 }
4081 activity.pendingResults.add(rec.ref);
4082 }
4083 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004084 }
4085
4086 public void cancelIntentSender(IIntentSender sender) {
4087 if (!(sender instanceof PendingIntentRecord)) {
4088 return;
4089 }
4090 synchronized(this) {
4091 PendingIntentRecord rec = (PendingIntentRecord)sender;
4092 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004093 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004094 .getPackageUid(rec.key.packageName);
4095 if (uid != Binder.getCallingUid()) {
4096 String msg = "Permission Denial: cancelIntentSender() from pid="
4097 + Binder.getCallingPid()
4098 + ", uid=" + Binder.getCallingUid()
4099 + " is not allowed to cancel packges "
4100 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004101 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004102 throw new SecurityException(msg);
4103 }
4104 } catch (RemoteException e) {
4105 throw new SecurityException(e);
4106 }
4107 cancelIntentSenderLocked(rec, true);
4108 }
4109 }
4110
4111 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4112 rec.canceled = true;
4113 mIntentSenderRecords.remove(rec.key);
4114 if (cleanActivity && rec.key.activity != null) {
4115 rec.key.activity.pendingResults.remove(rec.ref);
4116 }
4117 }
4118
4119 public String getPackageForIntentSender(IIntentSender pendingResult) {
4120 if (!(pendingResult instanceof PendingIntentRecord)) {
4121 return null;
4122 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004123 try {
4124 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4125 return res.key.packageName;
4126 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004127 }
4128 return null;
4129 }
4130
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004131 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4132 if (!(pendingResult instanceof PendingIntentRecord)) {
4133 return false;
4134 }
4135 try {
4136 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4137 if (res.key.allIntents == null) {
4138 return false;
4139 }
4140 for (int i=0; i<res.key.allIntents.length; i++) {
4141 Intent intent = res.key.allIntents[i];
4142 if (intent.getPackage() != null && intent.getComponent() != null) {
4143 return false;
4144 }
4145 }
4146 return true;
4147 } catch (ClassCastException e) {
4148 }
4149 return false;
4150 }
4151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004152 public void setProcessLimit(int max) {
4153 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4154 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004155 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004156 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004157 mProcessLimitOverride = max;
4158 }
4159 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004160 }
4161
4162 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004163 synchronized (this) {
4164 return mProcessLimitOverride;
4165 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 }
4167
4168 void foregroundTokenDied(ForegroundToken token) {
4169 synchronized (ActivityManagerService.this) {
4170 synchronized (mPidsSelfLocked) {
4171 ForegroundToken cur
4172 = mForegroundProcesses.get(token.pid);
4173 if (cur != token) {
4174 return;
4175 }
4176 mForegroundProcesses.remove(token.pid);
4177 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4178 if (pr == null) {
4179 return;
4180 }
4181 pr.forcingToForeground = null;
4182 pr.foregroundServices = false;
4183 }
4184 updateOomAdjLocked();
4185 }
4186 }
4187
4188 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4189 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4190 "setProcessForeground()");
4191 synchronized(this) {
4192 boolean changed = false;
4193
4194 synchronized (mPidsSelfLocked) {
4195 ProcessRecord pr = mPidsSelfLocked.get(pid);
4196 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004197 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004198 return;
4199 }
4200 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4201 if (oldToken != null) {
4202 oldToken.token.unlinkToDeath(oldToken, 0);
4203 mForegroundProcesses.remove(pid);
4204 pr.forcingToForeground = null;
4205 changed = true;
4206 }
4207 if (isForeground && token != null) {
4208 ForegroundToken newToken = new ForegroundToken() {
4209 public void binderDied() {
4210 foregroundTokenDied(this);
4211 }
4212 };
4213 newToken.pid = pid;
4214 newToken.token = token;
4215 try {
4216 token.linkToDeath(newToken, 0);
4217 mForegroundProcesses.put(pid, newToken);
4218 pr.forcingToForeground = token;
4219 changed = true;
4220 } catch (RemoteException e) {
4221 // If the process died while doing this, we will later
4222 // do the cleanup with the process death link.
4223 }
4224 }
4225 }
4226
4227 if (changed) {
4228 updateOomAdjLocked();
4229 }
4230 }
4231 }
4232
4233 // =========================================================
4234 // PERMISSIONS
4235 // =========================================================
4236
4237 static class PermissionController extends IPermissionController.Stub {
4238 ActivityManagerService mActivityManagerService;
4239 PermissionController(ActivityManagerService activityManagerService) {
4240 mActivityManagerService = activityManagerService;
4241 }
4242
4243 public boolean checkPermission(String permission, int pid, int uid) {
4244 return mActivityManagerService.checkPermission(permission, pid,
4245 uid) == PackageManager.PERMISSION_GRANTED;
4246 }
4247 }
4248
4249 /**
4250 * This can be called with or without the global lock held.
4251 */
4252 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004253 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004254 // We might be performing an operation on behalf of an indirect binder
4255 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4256 // client identity accordingly before proceeding.
4257 Identity tlsIdentity = sCallerIdentity.get();
4258 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004259 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004260 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4261 uid = tlsIdentity.uid;
4262 pid = tlsIdentity.pid;
4263 }
4264
4265 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004266 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004267 return PackageManager.PERMISSION_GRANTED;
4268 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004269 // If there is a uid that owns whatever is being accessed, it has
4270 // blanket access to it regardless of the permissions it requires.
4271 if (owningUid >= 0 && uid == owningUid) {
4272 return PackageManager.PERMISSION_GRANTED;
4273 }
4274 // If the target is not exported, then nobody else can get to it.
4275 if (!exported) {
4276 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004277 return PackageManager.PERMISSION_DENIED;
4278 }
4279 if (permission == null) {
4280 return PackageManager.PERMISSION_GRANTED;
4281 }
4282 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004283 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004284 .checkUidPermission(permission, uid);
4285 } catch (RemoteException e) {
4286 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004287 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004288 }
4289 return PackageManager.PERMISSION_DENIED;
4290 }
4291
4292 /**
4293 * As the only public entry point for permissions checking, this method
4294 * can enforce the semantic that requesting a check on a null global
4295 * permission is automatically denied. (Internally a null permission
4296 * string is used when calling {@link #checkComponentPermission} in cases
4297 * when only uid-based security is needed.)
4298 *
4299 * This can be called with or without the global lock held.
4300 */
4301 public int checkPermission(String permission, int pid, int uid) {
4302 if (permission == null) {
4303 return PackageManager.PERMISSION_DENIED;
4304 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004305 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 }
4307
4308 /**
4309 * Binder IPC calls go through the public entry point.
4310 * This can be called with or without the global lock held.
4311 */
4312 int checkCallingPermission(String permission) {
4313 return checkPermission(permission,
4314 Binder.getCallingPid(),
4315 Binder.getCallingUid());
4316 }
4317
4318 /**
4319 * This can be called with or without the global lock held.
4320 */
4321 void enforceCallingPermission(String permission, String func) {
4322 if (checkCallingPermission(permission)
4323 == PackageManager.PERMISSION_GRANTED) {
4324 return;
4325 }
4326
4327 String msg = "Permission Denial: " + func + " from pid="
4328 + Binder.getCallingPid()
4329 + ", uid=" + Binder.getCallingUid()
4330 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004331 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 throw new SecurityException(msg);
4333 }
4334
4335 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004336 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4337 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4338 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4339 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4340 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004341 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004342 // Is the component private from the target uid?
4343 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4344
4345 // Acceptable if the there is no read permission needed from the
4346 // target or the target is holding the read permission.
4347 if (!readPerm) {
4348 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004349 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004350 == PackageManager.PERMISSION_GRANTED)) {
4351 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004352 }
4353 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004354
4355 // Acceptable if the there is no write permission needed from the
4356 // target or the target is holding the read permission.
4357 if (!writePerm) {
4358 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004359 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004360 == PackageManager.PERMISSION_GRANTED)) {
4361 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004362 }
4363 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004364
4365 // Acceptable if there is a path permission matching the URI that
4366 // the target holds the permission on.
4367 PathPermission[] pps = pi.pathPermissions;
4368 if (pps != null && (!readPerm || !writePerm)) {
4369 final String path = uri.getPath();
4370 int i = pps.length;
4371 while (i > 0 && (!readPerm || !writePerm)) {
4372 i--;
4373 PathPermission pp = pps[i];
4374 if (!readPerm) {
4375 final String pprperm = pp.getReadPermission();
4376 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4377 + pprperm + " for " + pp.getPath()
4378 + ": match=" + pp.match(path)
4379 + " check=" + pm.checkUidPermission(pprperm, uid));
4380 if (pprperm != null && pp.match(path) &&
4381 (pm.checkUidPermission(pprperm, uid)
4382 == PackageManager.PERMISSION_GRANTED)) {
4383 readPerm = true;
4384 }
4385 }
4386 if (!writePerm) {
4387 final String ppwperm = pp.getWritePermission();
4388 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4389 + ppwperm + " for " + pp.getPath()
4390 + ": match=" + pp.match(path)
4391 + " check=" + pm.checkUidPermission(ppwperm, uid));
4392 if (ppwperm != null && pp.match(path) &&
4393 (pm.checkUidPermission(ppwperm, uid)
4394 == PackageManager.PERMISSION_GRANTED)) {
4395 writePerm = true;
4396 }
4397 }
4398 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004400 } catch (RemoteException e) {
4401 return false;
4402 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004403
4404 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004405 }
4406
4407 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4408 int modeFlags) {
4409 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004410 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004411 return true;
4412 }
4413 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4414 if (perms == null) return false;
4415 UriPermission perm = perms.get(uri);
4416 if (perm == null) return false;
4417 return (modeFlags&perm.modeFlags) == modeFlags;
4418 }
4419
4420 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4421 // Another redirected-binder-call permissions check as in
4422 // {@link checkComponentPermission}.
4423 Identity tlsIdentity = sCallerIdentity.get();
4424 if (tlsIdentity != null) {
4425 uid = tlsIdentity.uid;
4426 pid = tlsIdentity.pid;
4427 }
4428
4429 // Our own process gets to do everything.
4430 if (pid == MY_PID) {
4431 return PackageManager.PERMISSION_GRANTED;
4432 }
4433 synchronized(this) {
4434 return checkUriPermissionLocked(uri, uid, modeFlags)
4435 ? PackageManager.PERMISSION_GRANTED
4436 : PackageManager.PERMISSION_DENIED;
4437 }
4438 }
4439
Dianne Hackborn39792d22010-08-19 18:01:52 -07004440 /**
4441 * Check if the targetPkg can be granted permission to access uri by
4442 * the callingUid using the given modeFlags. Throws a security exception
4443 * if callingUid is not allowed to do this. Returns the uid of the target
4444 * if the URI permission grant should be performed; returns -1 if it is not
4445 * needed (for example targetPkg already has permission to access the URI).
4446 */
4447 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4448 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004449 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4450 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4451 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004452 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004453 }
4454
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004455 if (targetPkg != null) {
4456 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4457 "Checking grant " + targetPkg + " permission to " + uri);
4458 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004459
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004460 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004461
4462 // If this is not a content: uri, we can't do anything with it.
4463 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004464 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004465 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004466 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004467 }
4468
4469 String name = uri.getAuthority();
4470 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004471 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004472 if (cpr != null) {
4473 pi = cpr.info;
4474 } else {
4475 try {
4476 pi = pm.resolveContentProvider(name,
4477 PackageManager.GET_URI_PERMISSION_PATTERNS);
4478 } catch (RemoteException ex) {
4479 }
4480 }
4481 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004482 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004483 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004484 }
4485
4486 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004487 if (targetPkg != null) {
4488 try {
4489 targetUid = pm.getPackageUid(targetPkg);
4490 if (targetUid < 0) {
4491 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4492 "Can't grant URI permission no uid for: " + targetPkg);
4493 return -1;
4494 }
4495 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004496 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004497 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004498 } else {
4499 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004500 }
4501
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004502 if (targetUid >= 0) {
4503 // First... does the target actually need this permission?
4504 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4505 // No need to grant the target this permission.
4506 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4507 "Target " + targetPkg + " already has full permission to " + uri);
4508 return -1;
4509 }
4510 } else {
4511 // First... there is no target package, so can anyone access it?
4512 boolean allowed = pi.exported;
4513 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4514 if (pi.readPermission != null) {
4515 allowed = false;
4516 }
4517 }
4518 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4519 if (pi.writePermission != null) {
4520 allowed = false;
4521 }
4522 }
4523 if (allowed) {
4524 return -1;
4525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 }
4527
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004528 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004529 if (!pi.grantUriPermissions) {
4530 throw new SecurityException("Provider " + pi.packageName
4531 + "/" + pi.name
4532 + " does not allow granting of Uri permissions (uri "
4533 + uri + ")");
4534 }
4535 if (pi.uriPermissionPatterns != null) {
4536 final int N = pi.uriPermissionPatterns.length;
4537 boolean allowed = false;
4538 for (int i=0; i<N; i++) {
4539 if (pi.uriPermissionPatterns[i] != null
4540 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4541 allowed = true;
4542 break;
4543 }
4544 }
4545 if (!allowed) {
4546 throw new SecurityException("Provider " + pi.packageName
4547 + "/" + pi.name
4548 + " does not allow granting of permission to path of Uri "
4549 + uri);
4550 }
4551 }
4552
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004553 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004554 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004555 if (callingUid != Process.myUid()) {
4556 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4557 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4558 throw new SecurityException("Uid " + callingUid
4559 + " does not have permission to uri " + uri);
4560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004561 }
4562 }
4563
Dianne Hackborn39792d22010-08-19 18:01:52 -07004564 return targetUid;
4565 }
4566
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004567 public int checkGrantUriPermission(int callingUid, String targetPkg,
4568 Uri uri, int modeFlags) {
4569 synchronized(this) {
4570 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4571 }
4572 }
4573
Dianne Hackborn39792d22010-08-19 18:01:52 -07004574 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4575 Uri uri, int modeFlags, UriPermissionOwner owner) {
4576 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4577 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4578 if (modeFlags == 0) {
4579 return;
4580 }
4581
4582 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004583 // to the uri, and the target doesn't. Let's now give this to
4584 // the target.
4585
Joe Onorato8a9b2202010-02-26 18:56:32 -08004586 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004587 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004589 HashMap<Uri, UriPermission> targetUris
4590 = mGrantedUriPermissions.get(targetUid);
4591 if (targetUris == null) {
4592 targetUris = new HashMap<Uri, UriPermission>();
4593 mGrantedUriPermissions.put(targetUid, targetUris);
4594 }
4595
4596 UriPermission perm = targetUris.get(uri);
4597 if (perm == null) {
4598 perm = new UriPermission(targetUid, uri);
4599 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004602 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004603 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004604 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004605 } else {
4606 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4607 perm.readOwners.add(owner);
4608 owner.addReadPermission(perm);
4609 }
4610 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4611 perm.writeOwners.add(owner);
4612 owner.addWritePermission(perm);
4613 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 }
4615 }
4616
Dianne Hackborn39792d22010-08-19 18:01:52 -07004617 void grantUriPermissionLocked(int callingUid,
4618 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004619 if (targetPkg == null) {
4620 throw new NullPointerException("targetPkg");
4621 }
4622
Dianne Hackborn39792d22010-08-19 18:01:52 -07004623 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4624 if (targetUid < 0) {
4625 return;
4626 }
4627
4628 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4629 }
4630
4631 /**
4632 * Like checkGrantUriPermissionLocked, but takes an Intent.
4633 */
4634 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4635 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004636 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004637 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004638 + " from " + intent + "; flags=0x"
4639 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4640
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004641 if (targetPkg == null) {
4642 throw new NullPointerException("targetPkg");
4643 }
4644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004645 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004646 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 }
4648 Uri data = intent.getData();
4649 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004650 return -1;
4651 }
4652 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4653 intent.getFlags());
4654 }
4655
4656 /**
4657 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4658 */
4659 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4660 String targetPkg, Intent intent, UriPermissionOwner owner) {
4661 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4662 intent.getFlags(), owner);
4663 }
4664
4665 void grantUriPermissionFromIntentLocked(int callingUid,
4666 String targetPkg, Intent intent, UriPermissionOwner owner) {
4667 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4668 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004669 return;
4670 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004671
4672 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004673 }
4674
4675 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4676 Uri uri, int modeFlags) {
4677 synchronized(this) {
4678 final ProcessRecord r = getRecordForAppLocked(caller);
4679 if (r == null) {
4680 throw new SecurityException("Unable to find app for caller "
4681 + caller
4682 + " when granting permission to uri " + uri);
4683 }
4684 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004685 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004686 }
4687 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004688 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004689 }
4690
4691 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4692 null);
4693 }
4694 }
4695
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004696 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004697 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4698 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4699 HashMap<Uri, UriPermission> perms
4700 = mGrantedUriPermissions.get(perm.uid);
4701 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004702 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004703 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004704 perms.remove(perm.uri);
4705 if (perms.size() == 0) {
4706 mGrantedUriPermissions.remove(perm.uid);
4707 }
4708 }
4709 }
4710 }
4711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004712 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4713 int modeFlags) {
4714 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4715 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4716 if (modeFlags == 0) {
4717 return;
4718 }
4719
Joe Onorato8a9b2202010-02-26 18:56:32 -08004720 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004721 "Revoking all granted permissions to " + uri);
4722
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004723 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004724
4725 final String authority = uri.getAuthority();
4726 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004727 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004728 if (cpr != null) {
4729 pi = cpr.info;
4730 } else {
4731 try {
4732 pi = pm.resolveContentProvider(authority,
4733 PackageManager.GET_URI_PERMISSION_PATTERNS);
4734 } catch (RemoteException ex) {
4735 }
4736 }
4737 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004738 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004739 return;
4740 }
4741
4742 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004743 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004744 // Right now, if you are not the original owner of the permission,
4745 // you are not allowed to revoke it.
4746 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4747 throw new SecurityException("Uid " + callingUid
4748 + " does not have permission to uri " + uri);
4749 //}
4750 }
4751
4752 // Go through all of the permissions and remove any that match.
4753 final List<String> SEGMENTS = uri.getPathSegments();
4754 if (SEGMENTS != null) {
4755 final int NS = SEGMENTS.size();
4756 int N = mGrantedUriPermissions.size();
4757 for (int i=0; i<N; i++) {
4758 HashMap<Uri, UriPermission> perms
4759 = mGrantedUriPermissions.valueAt(i);
4760 Iterator<UriPermission> it = perms.values().iterator();
4761 toploop:
4762 while (it.hasNext()) {
4763 UriPermission perm = it.next();
4764 Uri targetUri = perm.uri;
4765 if (!authority.equals(targetUri.getAuthority())) {
4766 continue;
4767 }
4768 List<String> targetSegments = targetUri.getPathSegments();
4769 if (targetSegments == null) {
4770 continue;
4771 }
4772 if (targetSegments.size() < NS) {
4773 continue;
4774 }
4775 for (int j=0; j<NS; j++) {
4776 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4777 continue toploop;
4778 }
4779 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004780 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004781 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004782 perm.clearModes(modeFlags);
4783 if (perm.modeFlags == 0) {
4784 it.remove();
4785 }
4786 }
4787 if (perms.size() == 0) {
4788 mGrantedUriPermissions.remove(
4789 mGrantedUriPermissions.keyAt(i));
4790 N--;
4791 i--;
4792 }
4793 }
4794 }
4795 }
4796
4797 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4798 int modeFlags) {
4799 synchronized(this) {
4800 final ProcessRecord r = getRecordForAppLocked(caller);
4801 if (r == null) {
4802 throw new SecurityException("Unable to find app for caller "
4803 + caller
4804 + " when revoking permission to uri " + uri);
4805 }
4806 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004807 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004808 return;
4809 }
4810
4811 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4812 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4813 if (modeFlags == 0) {
4814 return;
4815 }
4816
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004817 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004818
4819 final String authority = uri.getAuthority();
4820 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004821 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004822 if (cpr != null) {
4823 pi = cpr.info;
4824 } else {
4825 try {
4826 pi = pm.resolveContentProvider(authority,
4827 PackageManager.GET_URI_PERMISSION_PATTERNS);
4828 } catch (RemoteException ex) {
4829 }
4830 }
4831 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004832 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004833 return;
4834 }
4835
4836 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4837 }
4838 }
4839
Dianne Hackborn7e269642010-08-25 19:50:20 -07004840 @Override
4841 public IBinder newUriPermissionOwner(String name) {
4842 synchronized(this) {
4843 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4844 return owner.getExternalTokenLocked();
4845 }
4846 }
4847
4848 @Override
4849 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4850 Uri uri, int modeFlags) {
4851 synchronized(this) {
4852 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4853 if (owner == null) {
4854 throw new IllegalArgumentException("Unknown owner: " + token);
4855 }
4856 if (fromUid != Binder.getCallingUid()) {
4857 if (Binder.getCallingUid() != Process.myUid()) {
4858 // Only system code can grant URI permissions on behalf
4859 // of other users.
4860 throw new SecurityException("nice try");
4861 }
4862 }
4863 if (targetPkg == null) {
4864 throw new IllegalArgumentException("null target");
4865 }
4866 if (uri == null) {
4867 throw new IllegalArgumentException("null uri");
4868 }
4869
4870 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4871 }
4872 }
4873
4874 @Override
4875 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4876 synchronized(this) {
4877 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4878 if (owner == null) {
4879 throw new IllegalArgumentException("Unknown owner: " + token);
4880 }
4881
4882 if (uri == null) {
4883 owner.removeUriPermissionsLocked(mode);
4884 } else {
4885 owner.removeUriPermissionLocked(uri, mode);
4886 }
4887 }
4888 }
4889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004890 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4891 synchronized (this) {
4892 ProcessRecord app =
4893 who != null ? getRecordForAppLocked(who) : null;
4894 if (app == null) return;
4895
4896 Message msg = Message.obtain();
4897 msg.what = WAIT_FOR_DEBUGGER_MSG;
4898 msg.obj = app;
4899 msg.arg1 = waiting ? 1 : 0;
4900 mHandler.sendMessage(msg);
4901 }
4902 }
4903
4904 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004905 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4906 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004907 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004908 outInfo.threshold = homeAppMem;
4909 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4910 outInfo.hiddenAppThreshold = hiddenAppMem;
4911 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4912 ProcessList.SECONDARY_SERVER_ADJ);
4913 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4914 ProcessList.VISIBLE_APP_ADJ);
4915 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4916 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004917 }
4918
4919 // =========================================================
4920 // TASK MANAGEMENT
4921 // =========================================================
4922
4923 public List getTasks(int maxNum, int flags,
4924 IThumbnailReceiver receiver) {
4925 ArrayList list = new ArrayList();
4926
4927 PendingThumbnailsRecord pending = null;
4928 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004929 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004930
4931 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004932 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4934 + ", receiver=" + receiver);
4935
4936 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4937 != PackageManager.PERMISSION_GRANTED) {
4938 if (receiver != null) {
4939 // If the caller wants to wait for pending thumbnails,
4940 // it ain't gonna get them.
4941 try {
4942 receiver.finished();
4943 } catch (RemoteException ex) {
4944 }
4945 }
4946 String msg = "Permission Denial: getTasks() from pid="
4947 + Binder.getCallingPid()
4948 + ", uid=" + Binder.getCallingUid()
4949 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004950 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004951 throw new SecurityException(msg);
4952 }
4953
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004954 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004955 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004956 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004957 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004958 TaskRecord curTask = null;
4959 int numActivities = 0;
4960 int numRunning = 0;
4961 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004962 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004963 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004964 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004965
4966 // Initialize state for next task if needed.
4967 if (top == null ||
4968 (top.state == ActivityState.INITIALIZING
4969 && top.task == r.task)) {
4970 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 curTask = r.task;
4972 numActivities = numRunning = 0;
4973 }
4974
4975 // Add 'r' into the current task.
4976 numActivities++;
4977 if (r.app != null && r.app.thread != null) {
4978 numRunning++;
4979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004980
Joe Onorato8a9b2202010-02-26 18:56:32 -08004981 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004982 TAG, r.intent.getComponent().flattenToShortString()
4983 + ": task=" + r.task);
4984
4985 // If the next one is a different task, generate a new
4986 // TaskInfo entry for what we have.
4987 if (next == null || next.task != curTask) {
4988 ActivityManager.RunningTaskInfo ci
4989 = new ActivityManager.RunningTaskInfo();
4990 ci.id = curTask.taskId;
4991 ci.baseActivity = r.intent.getComponent();
4992 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004993 if (top.thumbHolder != null) {
4994 ci.description = top.thumbHolder.lastDescription;
4995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004996 ci.numActivities = numActivities;
4997 ci.numRunning = numRunning;
4998 //System.out.println(
4999 // "#" + maxNum + ": " + " descr=" + ci.description);
5000 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005001 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005002 TAG, "State=" + top.state + "Idle=" + top.idle
5003 + " app=" + top.app
5004 + " thr=" + (top.app != null ? top.app.thread : null));
5005 if (top.state == ActivityState.RESUMED
5006 || top.state == ActivityState.PAUSING) {
5007 if (top.idle && top.app != null
5008 && top.app.thread != null) {
5009 topRecord = top;
5010 topThumbnail = top.app.thread;
5011 } else {
5012 top.thumbnailNeeded = true;
5013 }
5014 }
5015 if (pending == null) {
5016 pending = new PendingThumbnailsRecord(receiver);
5017 }
5018 pending.pendingRecords.add(top);
5019 }
5020 list.add(ci);
5021 maxNum--;
5022 top = null;
5023 }
5024 }
5025
5026 if (pending != null) {
5027 mPendingThumbnails.add(pending);
5028 }
5029 }
5030
Joe Onorato8a9b2202010-02-26 18:56:32 -08005031 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005032
5033 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005034 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005035 try {
5036 topThumbnail.requestThumbnail(topRecord);
5037 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005038 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005039 sendPendingThumbnail(null, topRecord, null, null, true);
5040 }
5041 }
5042
5043 if (pending == null && receiver != null) {
5044 // In this case all thumbnails were available and the client
5045 // is being asked to be told when the remaining ones come in...
5046 // which is unusually, since the top-most currently running
5047 // activity should never have a canned thumbnail! Oh well.
5048 try {
5049 receiver.finished();
5050 } catch (RemoteException ex) {
5051 }
5052 }
5053
5054 return list;
5055 }
5056
5057 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5058 int flags) {
5059 synchronized (this) {
5060 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5061 "getRecentTasks()");
5062
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005063 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005065 final int N = mRecentTasks.size();
5066 ArrayList<ActivityManager.RecentTaskInfo> res
5067 = new ArrayList<ActivityManager.RecentTaskInfo>(
5068 maxNum < N ? maxNum : N);
5069 for (int i=0; i<N && maxNum > 0; i++) {
5070 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005071 // Return the entry if desired by the caller. We always return
5072 // the first entry, because callers always expect this to be the
5073 // forground app. We may filter others if the caller has
5074 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5075 // we should exclude the entry.
5076 if (i == 0
5077 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005078 || (tr.intent == null)
5079 || ((tr.intent.getFlags()
5080 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5081 ActivityManager.RecentTaskInfo rti
5082 = new ActivityManager.RecentTaskInfo();
5083 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005084 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005085 rti.baseIntent = new Intent(
5086 tr.intent != null ? tr.intent : tr.affinityIntent);
5087 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005088 rti.description = tr.lastDescription;
5089
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005090 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5091 // Check whether this activity is currently available.
5092 try {
5093 if (rti.origActivity != null) {
5094 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5095 continue;
5096 }
5097 } else if (rti.baseIntent != null) {
5098 if (pm.queryIntentActivities(rti.baseIntent,
5099 null, 0) == null) {
5100 continue;
5101 }
5102 }
5103 } catch (RemoteException e) {
5104 // Will never happen.
5105 }
5106 }
5107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005108 res.add(rti);
5109 maxNum--;
5110 }
5111 }
5112 return res;
5113 }
5114 }
5115
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005116 private TaskRecord taskForIdLocked(int id) {
5117 final int N = mRecentTasks.size();
5118 for (int i=0; i<N; i++) {
5119 TaskRecord tr = mRecentTasks.get(i);
5120 if (tr.taskId == id) {
5121 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005122 }
5123 }
5124 return null;
5125 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005126
5127 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5128 synchronized (this) {
5129 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5130 "getTaskThumbnails()");
5131 TaskRecord tr = taskForIdLocked(id);
5132 if (tr != null) {
5133 return mMainStack.getTaskThumbnailsLocked(tr);
5134 }
5135 }
5136 return null;
5137 }
5138
5139 public boolean removeSubTask(int taskId, int subTaskIndex) {
5140 synchronized (this) {
5141 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5142 "removeSubTask()");
5143 long ident = Binder.clearCallingIdentity();
5144 try {
5145 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5146 } finally {
5147 Binder.restoreCallingIdentity(ident);
5148 }
5149 }
5150 }
5151
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005152 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005153 TaskRecord tr = root.task;
5154 Intent baseIntent = new Intent(
5155 tr.intent != null ? tr.intent : tr.affinityIntent);
5156 ComponentName component = baseIntent.getComponent();
5157 if (component == null) {
5158 Slog.w(TAG, "Now component for base intent of task: " + tr);
5159 return;
5160 }
5161
5162 // Find any running services associated with this app.
5163 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5164 for (ServiceRecord sr : mServices.values()) {
5165 if (sr.packageName.equals(component.getPackageName())) {
5166 services.add(sr);
5167 }
5168 }
5169
5170 // Take care of any running services associated with the app.
5171 for (int i=0; i<services.size(); i++) {
5172 ServiceRecord sr = services.get(i);
5173 if (sr.startRequested) {
5174 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005175 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005176 stopServiceLocked(sr);
5177 } else {
5178 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5179 sr.makeNextStartId(), baseIntent, -1));
5180 if (sr.app != null && sr.app.thread != null) {
5181 sendServiceArgsLocked(sr, false);
5182 }
5183 }
5184 }
5185 }
5186
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005187 if (killProcesses) {
5188 // Find any running processes associated with this app.
5189 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5190 SparseArray<ProcessRecord> appProcs
5191 = mProcessNames.getMap().get(component.getPackageName());
5192 if (appProcs != null) {
5193 for (int i=0; i<appProcs.size(); i++) {
5194 procs.add(appProcs.valueAt(i));
5195 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005196 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005197
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005198 // Kill the running processes.
5199 for (int i=0; i<procs.size(); i++) {
5200 ProcessRecord pr = procs.get(i);
5201 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5202 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5203 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5204 pr.processName, pr.setAdj, "remove task");
5205 Process.killProcessQuiet(pr.pid);
5206 } else {
5207 pr.waitingToKill = "remove task";
5208 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005209 }
5210 }
5211 }
5212
5213 public boolean removeTask(int taskId, int flags) {
5214 synchronized (this) {
5215 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5216 "removeTask()");
5217 long ident = Binder.clearCallingIdentity();
5218 try {
5219 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5220 if (r != null) {
5221 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005222 cleanUpRemovedTaskLocked(r,
5223 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005224 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005225 } else {
5226 TaskRecord tr = null;
5227 int i=0;
5228 while (i < mRecentTasks.size()) {
5229 TaskRecord t = mRecentTasks.get(i);
5230 if (t.taskId == taskId) {
5231 tr = t;
5232 break;
5233 }
5234 i++;
5235 }
5236 if (tr != null) {
5237 if (tr.numActivities <= 0) {
5238 // Caller is just removing a recent task that is
5239 // not actively running. That is easy!
5240 mRecentTasks.remove(i);
5241 } else {
5242 Slog.w(TAG, "removeTask: task " + taskId
5243 + " does not have activities to remove, "
5244 + " but numActivities=" + tr.numActivities
5245 + ": " + tr);
5246 }
5247 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005248 }
5249 } finally {
5250 Binder.restoreCallingIdentity(ident);
5251 }
5252 }
5253 return false;
5254 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005256 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5257 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005258 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005259 TaskRecord jt = startTask;
5260
5261 // First look backwards
5262 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005263 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005264 if (r.task != jt) {
5265 jt = r.task;
5266 if (affinity.equals(jt.affinity)) {
5267 return j;
5268 }
5269 }
5270 }
5271
5272 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005273 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005274 jt = startTask;
5275 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005276 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005277 if (r.task != jt) {
5278 if (affinity.equals(jt.affinity)) {
5279 return j;
5280 }
5281 jt = r.task;
5282 }
5283 }
5284
5285 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005286 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005287 return N-1;
5288 }
5289
5290 return -1;
5291 }
5292
5293 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005294 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005295 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005296 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005297 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5298 "moveTaskToFront()");
5299
5300 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005301 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5302 Binder.getCallingUid(), "Task to front")) {
5303 return;
5304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005305 final long origId = Binder.clearCallingIdentity();
5306 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005307 TaskRecord tr = taskForIdLocked(task);
5308 if (tr != null) {
5309 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5310 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005311 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005312 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5313 // Caller wants the home activity moved with it. To accomplish this,
5314 // we'll just move the home task to the top first.
5315 mMainStack.moveHomeToFrontLocked();
5316 }
5317 mMainStack.moveTaskToFrontLocked(tr, null);
5318 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005319 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005320 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5321 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005322 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005323 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5324 mMainStack.mUserLeaving = true;
5325 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005326 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5327 // Caller wants the home activity moved with it. To accomplish this,
5328 // we'll just move the home task to the top first.
5329 mMainStack.moveHomeToFrontLocked();
5330 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005331 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005332 return;
5333 }
5334 }
5335 } finally {
5336 Binder.restoreCallingIdentity(origId);
5337 }
5338 }
5339 }
5340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005341 public void moveTaskToBack(int task) {
5342 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5343 "moveTaskToBack()");
5344
5345 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005346 if (mMainStack.mResumedActivity != null
5347 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005348 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5349 Binder.getCallingUid(), "Task to back")) {
5350 return;
5351 }
5352 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005353 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005354 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005355 Binder.restoreCallingIdentity(origId);
5356 }
5357 }
5358
5359 /**
5360 * Moves an activity, and all of the other activities within the same task, to the bottom
5361 * of the history stack. The activity's order within the task is unchanged.
5362 *
5363 * @param token A reference to the activity we wish to move
5364 * @param nonRoot If false then this only works if the activity is the root
5365 * of a task; if true it will work for any activity in a task.
5366 * @return Returns true if the move completed, false if not.
5367 */
5368 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5369 synchronized(this) {
5370 final long origId = Binder.clearCallingIdentity();
5371 int taskId = getTaskForActivityLocked(token, !nonRoot);
5372 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005373 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005374 }
5375 Binder.restoreCallingIdentity(origId);
5376 }
5377 return false;
5378 }
5379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005380 public void moveTaskBackwards(int task) {
5381 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5382 "moveTaskBackwards()");
5383
5384 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005385 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5386 Binder.getCallingUid(), "Task backwards")) {
5387 return;
5388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005389 final long origId = Binder.clearCallingIdentity();
5390 moveTaskBackwardsLocked(task);
5391 Binder.restoreCallingIdentity(origId);
5392 }
5393 }
5394
5395 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005396 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005397 }
5398
5399 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5400 synchronized(this) {
5401 return getTaskForActivityLocked(token, onlyRoot);
5402 }
5403 }
5404
5405 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005406 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005407 TaskRecord lastTask = null;
5408 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005409 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005410 if (r == token) {
5411 if (!onlyRoot || lastTask != r.task) {
5412 return r.task.taskId;
5413 }
5414 return -1;
5415 }
5416 lastTask = r.task;
5417 }
5418
5419 return -1;
5420 }
5421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005422 public void finishOtherInstances(IBinder token, ComponentName className) {
5423 synchronized(this) {
5424 final long origId = Binder.clearCallingIdentity();
5425
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005426 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005427 TaskRecord lastTask = null;
5428 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005429 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005430 if (r.realActivity.equals(className)
5431 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005432 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005433 null, "others")) {
5434 i--;
5435 N--;
5436 }
5437 }
5438 lastTask = r.task;
5439 }
5440
5441 Binder.restoreCallingIdentity(origId);
5442 }
5443 }
5444
5445 // =========================================================
5446 // THUMBNAILS
5447 // =========================================================
5448
5449 public void reportThumbnail(IBinder token,
5450 Bitmap thumbnail, CharSequence description) {
5451 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5452 final long origId = Binder.clearCallingIdentity();
5453 sendPendingThumbnail(null, token, thumbnail, description, true);
5454 Binder.restoreCallingIdentity(origId);
5455 }
5456
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005457 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005458 Bitmap thumbnail, CharSequence description, boolean always) {
5459 TaskRecord task = null;
5460 ArrayList receivers = null;
5461
5462 //System.out.println("Send pending thumbnail: " + r);
5463
5464 synchronized(this) {
5465 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005466 r = mMainStack.isInStackLocked(token);
5467 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005468 return;
5469 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005470 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005471 if (thumbnail == null && r.thumbHolder != null) {
5472 thumbnail = r.thumbHolder.lastThumbnail;
5473 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005474 }
5475 if (thumbnail == null && !always) {
5476 // If there is no thumbnail, and this entry is not actually
5477 // going away, then abort for now and pick up the next
5478 // thumbnail we get.
5479 return;
5480 }
5481 task = r.task;
5482
5483 int N = mPendingThumbnails.size();
5484 int i=0;
5485 while (i<N) {
5486 PendingThumbnailsRecord pr =
5487 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5488 //System.out.println("Looking in " + pr.pendingRecords);
5489 if (pr.pendingRecords.remove(r)) {
5490 if (receivers == null) {
5491 receivers = new ArrayList();
5492 }
5493 receivers.add(pr);
5494 if (pr.pendingRecords.size() == 0) {
5495 pr.finished = true;
5496 mPendingThumbnails.remove(i);
5497 N--;
5498 continue;
5499 }
5500 }
5501 i++;
5502 }
5503 }
5504
5505 if (receivers != null) {
5506 final int N = receivers.size();
5507 for (int i=0; i<N; i++) {
5508 try {
5509 PendingThumbnailsRecord pr =
5510 (PendingThumbnailsRecord)receivers.get(i);
5511 pr.receiver.newThumbnail(
5512 task != null ? task.taskId : -1, thumbnail, description);
5513 if (pr.finished) {
5514 pr.receiver.finished();
5515 }
5516 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005517 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005518 }
5519 }
5520 }
5521 }
5522
5523 // =========================================================
5524 // CONTENT PROVIDERS
5525 // =========================================================
5526
Jeff Brown10e89712011-07-08 18:52:57 -07005527 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5528 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005529 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005530 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005531 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005532 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005533 } catch (RemoteException ex) {
5534 }
5535 if (providers != null) {
5536 final int N = providers.size();
5537 for (int i=0; i<N; i++) {
5538 ProviderInfo cpi =
5539 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005540 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5541 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005542 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005543 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005544 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005545 }
5546 app.pubProviders.put(cpi.name, cpr);
5547 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005548 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005549 }
5550 }
5551 return providers;
5552 }
5553
5554 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005555 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005556 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5557 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5558 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005559 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005560 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005561 return null;
5562 }
5563 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005564 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005565 == PackageManager.PERMISSION_GRANTED) {
5566 return null;
5567 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005568
5569 PathPermission[] pps = cpi.pathPermissions;
5570 if (pps != null) {
5571 int i = pps.length;
5572 while (i > 0) {
5573 i--;
5574 PathPermission pp = pps[i];
5575 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005576 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005577 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005578 return null;
5579 }
5580 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005581 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005582 == PackageManager.PERMISSION_GRANTED) {
5583 return null;
5584 }
5585 }
5586 }
5587
Dianne Hackbornb424b632010-08-18 15:59:05 -07005588 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5589 if (perms != null) {
5590 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5591 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5592 return null;
5593 }
5594 }
5595 }
5596
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005597 String msg;
5598 if (!cpi.exported) {
5599 msg = "Permission Denial: opening provider " + cpi.name
5600 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5601 + ", uid=" + callingUid + ") that is not exported from uid "
5602 + cpi.applicationInfo.uid;
5603 } else {
5604 msg = "Permission Denial: opening provider " + cpi.name
5605 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5606 + ", uid=" + callingUid + ") requires "
5607 + cpi.readPermission + " or " + cpi.writePermission;
5608 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005609 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005610 return msg;
5611 }
5612
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005613 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5614 if (r != null) {
5615 Integer cnt = r.conProviders.get(cpr);
5616 if (DEBUG_PROVIDER) Slog.v(TAG,
5617 "Adding provider requested by "
5618 + r.processName + " from process "
5619 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5620 + " cnt=" + (cnt == null ? 1 : cnt));
5621 if (cnt == null) {
5622 cpr.clients.add(r);
5623 r.conProviders.put(cpr, new Integer(1));
5624 return true;
5625 } else {
5626 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5627 }
5628 } else {
5629 cpr.externals++;
5630 }
5631 return false;
5632 }
5633
5634 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5635 if (r != null) {
5636 Integer cnt = r.conProviders.get(cpr);
5637 if (DEBUG_PROVIDER) Slog.v(TAG,
5638 "Removing provider requested by "
5639 + r.processName + " from process "
5640 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5641 + " cnt=" + cnt);
5642 if (cnt == null || cnt.intValue() <= 1) {
5643 cpr.clients.remove(r);
5644 r.conProviders.remove(cpr);
5645 return true;
5646 } else {
5647 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5648 }
5649 } else {
5650 cpr.externals++;
5651 }
5652 return false;
5653 }
5654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005655 private final ContentProviderHolder getContentProviderImpl(
5656 IApplicationThread caller, String name) {
5657 ContentProviderRecord cpr;
5658 ProviderInfo cpi = null;
5659
5660 synchronized(this) {
5661 ProcessRecord r = null;
5662 if (caller != null) {
5663 r = getRecordForAppLocked(caller);
5664 if (r == null) {
5665 throw new SecurityException(
5666 "Unable to find app for caller " + caller
5667 + " (pid=" + Binder.getCallingPid()
5668 + ") when getting content provider " + name);
5669 }
5670 }
5671
5672 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005673 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005674 boolean providerRunning = cpr != null;
5675 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005676 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005677 String msg;
5678 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5679 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005680 }
5681
5682 if (r != null && cpr.canRunHere(r)) {
5683 // This provider has been published or is in the process
5684 // of being published... but it is also allowed to run
5685 // in the caller's process, so don't make a connection
5686 // and just let the caller instantiate its own instance.
5687 if (cpr.provider != null) {
5688 // don't give caller the provider object, it needs
5689 // to make its own.
5690 cpr = new ContentProviderRecord(cpr);
5691 }
5692 return cpr;
5693 }
5694
5695 final long origId = Binder.clearCallingIdentity();
5696
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005697 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005698 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005699 final boolean countChanged = incProviderCount(r, cpr);
5700 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005701 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005702 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005703 // make sure to count it as being accessed and thus
5704 // back up on the LRU list. This is good because
5705 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005706 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005707 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005708 }
5709
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005710 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005711 if (false) {
5712 if (cpr.name.flattenToShortString().equals(
5713 "com.android.providers.calendar/.CalendarProvider2")) {
5714 Slog.v(TAG, "****************** KILLING "
5715 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005716 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005717 }
5718 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005719 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005720 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5721 // NOTE: there is still a race here where a signal could be
5722 // pending on the process even though we managed to update its
5723 // adj level. Not sure what to do about this, but at least
5724 // the race is now smaller.
5725 if (!success) {
5726 // Uh oh... it looks like the provider's process
5727 // has been killed on us. We need to wait for a new
5728 // process to be started, and make sure its death
5729 // doesn't kill our process.
5730 Slog.i(TAG,
5731 "Existing provider " + cpr.name.flattenToShortString()
5732 + " is crashing; detaching " + r);
5733 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005734 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005735 if (!lastRef) {
5736 // This wasn't the last ref our process had on
5737 // the provider... we have now been killed, bail.
5738 return null;
5739 }
5740 providerRunning = false;
5741 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005742 }
5743
5744 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005745 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005746
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005747 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005748 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005749 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005750 resolveContentProvider(name,
5751 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005752 } catch (RemoteException ex) {
5753 }
5754 if (cpi == null) {
5755 return null;
5756 }
5757
Dianne Hackbornb424b632010-08-18 15:59:05 -07005758 String msg;
5759 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5760 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005761 }
5762
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005763 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005764 && !cpi.processName.equals("system")) {
5765 // If this content provider does not run in the system
5766 // process, and the system is not yet ready to run other
5767 // processes, then fail fast instead of hanging.
5768 throw new IllegalArgumentException(
5769 "Attempt to launch content provider before system ready");
5770 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005771
5772 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5773 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005774 final boolean firstClass = cpr == null;
5775 if (firstClass) {
5776 try {
5777 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005778 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005779 getApplicationInfo(
5780 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005781 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005782 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005783 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005784 + cpi.name);
5785 return null;
5786 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005787 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005788 } catch (RemoteException ex) {
5789 // pm is in same process, this will never happen.
5790 }
5791 }
5792
5793 if (r != null && cpr.canRunHere(r)) {
5794 // If this is a multiprocess provider, then just return its
5795 // info and allow the caller to instantiate it. Only do
5796 // this if the provider is the same user as the caller's
5797 // process, or can run as root (so can be in any process).
5798 return cpr;
5799 }
5800
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005801 if (DEBUG_PROVIDER) {
5802 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005803 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005804 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005805 }
5806
5807 // This is single process, and our app is now connecting to it.
5808 // See if we are already in the process of launching this
5809 // provider.
5810 final int N = mLaunchingProviders.size();
5811 int i;
5812 for (i=0; i<N; i++) {
5813 if (mLaunchingProviders.get(i) == cpr) {
5814 break;
5815 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005816 }
5817
5818 // If the provider is not already being launched, then get it
5819 // started.
5820 if (i >= N) {
5821 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005822
5823 try {
5824 // Content provider is now in use, its package can't be stopped.
5825 try {
5826 AppGlobals.getPackageManager().setPackageStoppedState(
5827 cpr.appInfo.packageName, false);
5828 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005829 } catch (IllegalArgumentException e) {
5830 Slog.w(TAG, "Failed trying to unstop package "
5831 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005832 }
5833
5834 ProcessRecord proc = startProcessLocked(cpi.processName,
5835 cpr.appInfo, false, 0, "content provider",
5836 new ComponentName(cpi.applicationInfo.packageName,
5837 cpi.name), false);
5838 if (proc == null) {
5839 Slog.w(TAG, "Unable to launch app "
5840 + cpi.applicationInfo.packageName + "/"
5841 + cpi.applicationInfo.uid + " for provider "
5842 + name + ": process is bad");
5843 return null;
5844 }
5845 cpr.launchingApp = proc;
5846 mLaunchingProviders.add(cpr);
5847 } finally {
5848 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005849 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005850 }
5851
5852 // Make sure the provider is published (the same provider class
5853 // may be published under multiple names).
5854 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005855 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005856 }
5857 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005858 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005859 }
5860 }
5861
5862 // Wait for the provider to be published...
5863 synchronized (cpr) {
5864 while (cpr.provider == null) {
5865 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005866 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005867 + cpi.applicationInfo.packageName + "/"
5868 + cpi.applicationInfo.uid + " for provider "
5869 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005870 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005871 cpi.applicationInfo.packageName,
5872 cpi.applicationInfo.uid, name);
5873 return null;
5874 }
5875 try {
5876 cpr.wait();
5877 } catch (InterruptedException ex) {
5878 }
5879 }
5880 }
5881 return cpr;
5882 }
5883
5884 public final ContentProviderHolder getContentProvider(
5885 IApplicationThread caller, String name) {
5886 if (caller == null) {
5887 String msg = "null IApplicationThread when getting content provider "
5888 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005889 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005890 throw new SecurityException(msg);
5891 }
5892
5893 return getContentProviderImpl(caller, name);
5894 }
5895
5896 private ContentProviderHolder getContentProviderExternal(String name) {
5897 return getContentProviderImpl(null, name);
5898 }
5899
5900 /**
5901 * Drop a content provider from a ProcessRecord's bookkeeping
5902 * @param cpr
5903 */
5904 public void removeContentProvider(IApplicationThread caller, String name) {
5905 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005906 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005907 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005908 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005909 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005910 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005911 return;
5912 }
5913 final ProcessRecord r = getRecordForAppLocked(caller);
5914 if (r == null) {
5915 throw new SecurityException(
5916 "Unable to find app for caller " + caller +
5917 " when removing content provider " + name);
5918 }
5919 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005920 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5921 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005922 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005923 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005924 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005925 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005926 return;
5927 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005928 if (decProviderCount(r, localCpr)) {
5929 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005930 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005931 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005932 }
5933 }
5934
5935 private void removeContentProviderExternal(String name) {
5936 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005937 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005938 if(cpr == null) {
5939 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005940 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005941 return;
5942 }
5943
5944 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005945 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5946 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005947 localCpr.externals--;
5948 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005949 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005950 }
5951 updateOomAdjLocked();
5952 }
5953 }
5954
5955 public final void publishContentProviders(IApplicationThread caller,
5956 List<ContentProviderHolder> providers) {
5957 if (providers == null) {
5958 return;
5959 }
5960
5961 synchronized(this) {
5962 final ProcessRecord r = getRecordForAppLocked(caller);
5963 if (r == null) {
5964 throw new SecurityException(
5965 "Unable to find app for caller " + caller
5966 + " (pid=" + Binder.getCallingPid()
5967 + ") when publishing content providers");
5968 }
5969
5970 final long origId = Binder.clearCallingIdentity();
5971
5972 final int N = providers.size();
5973 for (int i=0; i<N; i++) {
5974 ContentProviderHolder src = providers.get(i);
5975 if (src == null || src.info == null || src.provider == null) {
5976 continue;
5977 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005978 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005979 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005980 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
5981 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005982 String names[] = dst.info.authority.split(";");
5983 for (int j = 0; j < names.length; j++) {
5984 mProvidersByName.put(names[j], dst);
5985 }
5986
5987 int NL = mLaunchingProviders.size();
5988 int j;
5989 for (j=0; j<NL; j++) {
5990 if (mLaunchingProviders.get(j) == dst) {
5991 mLaunchingProviders.remove(j);
5992 j--;
5993 NL--;
5994 }
5995 }
5996 synchronized (dst) {
5997 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005998 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005999 dst.notifyAll();
6000 }
6001 updateOomAdjLocked(r);
6002 }
6003 }
6004
6005 Binder.restoreCallingIdentity(origId);
6006 }
6007 }
6008
6009 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006010 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006011 synchronized (mSelf) {
6012 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6013 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006014 if (providers != null) {
6015 for (int i=providers.size()-1; i>=0; i--) {
6016 ProviderInfo pi = (ProviderInfo)providers.get(i);
6017 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6018 Slog.w(TAG, "Not installing system proc provider " + pi.name
6019 + ": not system .apk");
6020 providers.remove(i);
6021 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006022 }
6023 }
6024 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006025 if (providers != null) {
6026 mSystemThread.installSystemProviders(providers);
6027 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006028
6029 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006030
6031 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006032 }
6033
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006034 /**
6035 * Allows app to retrieve the MIME type of a URI without having permission
6036 * to access its content provider.
6037 *
6038 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6039 *
6040 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6041 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6042 */
6043 public String getProviderMimeType(Uri uri) {
6044 final String name = uri.getAuthority();
6045 final long ident = Binder.clearCallingIdentity();
6046 ContentProviderHolder holder = null;
6047
6048 try {
6049 holder = getContentProviderExternal(name);
6050 if (holder != null) {
6051 return holder.provider.getType(uri);
6052 }
6053 } catch (RemoteException e) {
6054 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6055 return null;
6056 } finally {
6057 if (holder != null) {
6058 removeContentProviderExternal(name);
6059 }
6060 Binder.restoreCallingIdentity(ident);
6061 }
6062
6063 return null;
6064 }
6065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 // =========================================================
6067 // GLOBAL MANAGEMENT
6068 // =========================================================
6069
6070 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6071 ApplicationInfo info, String customProcess) {
6072 String proc = customProcess != null ? customProcess : info.processName;
6073 BatteryStatsImpl.Uid.Proc ps = null;
6074 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6075 synchronized (stats) {
6076 ps = stats.getProcessStatsLocked(info.uid, proc);
6077 }
6078 return new ProcessRecord(ps, thread, info, proc);
6079 }
6080
6081 final ProcessRecord addAppLocked(ApplicationInfo info) {
6082 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6083
6084 if (app == null) {
6085 app = newProcessRecordLocked(null, info, null);
6086 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006087 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006088 }
6089
Dianne Hackborne7f97212011-02-24 14:40:20 -08006090 // This package really, really can not be stopped.
6091 try {
6092 AppGlobals.getPackageManager().setPackageStoppedState(
6093 info.packageName, false);
6094 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006095 } catch (IllegalArgumentException e) {
6096 Slog.w(TAG, "Failed trying to unstop package "
6097 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006098 }
6099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006100 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6101 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6102 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07006103 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006104 }
6105 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6106 mPersistentStartingProcesses.add(app);
6107 startProcessLocked(app, "added application", app.processName);
6108 }
6109
6110 return app;
6111 }
6112
6113 public void unhandledBack() {
6114 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6115 "unhandledBack()");
6116
6117 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006118 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006119 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006120 TAG, "Performing unhandledBack(): stack size = " + count);
6121 if (count > 1) {
6122 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006123 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006124 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6125 Binder.restoreCallingIdentity(origId);
6126 }
6127 }
6128 }
6129
6130 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6131 String name = uri.getAuthority();
6132 ContentProviderHolder cph = getContentProviderExternal(name);
6133 ParcelFileDescriptor pfd = null;
6134 if (cph != null) {
6135 // We record the binder invoker's uid in thread-local storage before
6136 // going to the content provider to open the file. Later, in the code
6137 // that handles all permissions checks, we look for this uid and use
6138 // that rather than the Activity Manager's own uid. The effect is that
6139 // we do the check against the caller's permissions even though it looks
6140 // to the content provider like the Activity Manager itself is making
6141 // the request.
6142 sCallerIdentity.set(new Identity(
6143 Binder.getCallingPid(), Binder.getCallingUid()));
6144 try {
6145 pfd = cph.provider.openFile(uri, "r");
6146 } catch (FileNotFoundException e) {
6147 // do nothing; pfd will be returned null
6148 } finally {
6149 // Ensure that whatever happens, we clean up the identity state
6150 sCallerIdentity.remove();
6151 }
6152
6153 // We've got the fd now, so we're done with the provider.
6154 removeContentProviderExternal(name);
6155 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006156 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006157 }
6158 return pfd;
6159 }
6160
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006161 // Actually is sleeping or shutting down or whatever else in the future
6162 // is an inactive state.
6163 public boolean isSleeping() {
6164 return mSleeping || mShuttingDown;
6165 }
6166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006167 public void goingToSleep() {
6168 synchronized(this) {
6169 mSleeping = true;
6170 mWindowManager.setEventDispatching(false);
6171
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006172 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006173
6174 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006175 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006176 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6177 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006178 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006179 }
6180 }
6181
Dianne Hackborn55280a92009-05-07 15:53:46 -07006182 public boolean shutdown(int timeout) {
6183 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6184 != PackageManager.PERMISSION_GRANTED) {
6185 throw new SecurityException("Requires permission "
6186 + android.Manifest.permission.SHUTDOWN);
6187 }
6188
6189 boolean timedout = false;
6190
6191 synchronized(this) {
6192 mShuttingDown = true;
6193 mWindowManager.setEventDispatching(false);
6194
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006195 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006196 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006197 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006198 while (mMainStack.mResumedActivity != null
6199 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006200 long delay = endTime - System.currentTimeMillis();
6201 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006202 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006203 timedout = true;
6204 break;
6205 }
6206 try {
6207 this.wait();
6208 } catch (InterruptedException e) {
6209 }
6210 }
6211 }
6212 }
6213
6214 mUsageStatsService.shutdown();
6215 mBatteryStatsService.shutdown();
6216
6217 return timedout;
6218 }
6219
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006220 public final void activitySlept(IBinder token) {
6221 if (localLOGV) Slog.v(
6222 TAG, "Activity slept: token=" + token);
6223
6224 ActivityRecord r = null;
6225
6226 final long origId = Binder.clearCallingIdentity();
6227
6228 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006229 r = mMainStack.isInStackLocked(token);
6230 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006231 mMainStack.activitySleptLocked(r);
6232 }
6233 }
6234
6235 Binder.restoreCallingIdentity(origId);
6236 }
6237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006238 public void wakingUp() {
6239 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006240 mWindowManager.setEventDispatching(true);
6241 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006242 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006243 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006244 }
6245 }
6246
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006247 public void stopAppSwitches() {
6248 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6249 != PackageManager.PERMISSION_GRANTED) {
6250 throw new SecurityException("Requires permission "
6251 + android.Manifest.permission.STOP_APP_SWITCHES);
6252 }
6253
6254 synchronized(this) {
6255 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6256 + APP_SWITCH_DELAY_TIME;
6257 mDidAppSwitch = false;
6258 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6259 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6260 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6261 }
6262 }
6263
6264 public void resumeAppSwitches() {
6265 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6266 != PackageManager.PERMISSION_GRANTED) {
6267 throw new SecurityException("Requires permission "
6268 + android.Manifest.permission.STOP_APP_SWITCHES);
6269 }
6270
6271 synchronized(this) {
6272 // Note that we don't execute any pending app switches... we will
6273 // let those wait until either the timeout, or the next start
6274 // activity request.
6275 mAppSwitchesAllowedTime = 0;
6276 }
6277 }
6278
6279 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6280 String name) {
6281 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6282 return true;
6283 }
6284
6285 final int perm = checkComponentPermission(
6286 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006287 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006288 if (perm == PackageManager.PERMISSION_GRANTED) {
6289 return true;
6290 }
6291
Joe Onorato8a9b2202010-02-26 18:56:32 -08006292 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006293 return false;
6294 }
6295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 public void setDebugApp(String packageName, boolean waitForDebugger,
6297 boolean persistent) {
6298 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6299 "setDebugApp()");
6300
6301 // Note that this is not really thread safe if there are multiple
6302 // callers into it at the same time, but that's not a situation we
6303 // care about.
6304 if (persistent) {
6305 final ContentResolver resolver = mContext.getContentResolver();
6306 Settings.System.putString(
6307 resolver, Settings.System.DEBUG_APP,
6308 packageName);
6309 Settings.System.putInt(
6310 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6311 waitForDebugger ? 1 : 0);
6312 }
6313
6314 synchronized (this) {
6315 if (!persistent) {
6316 mOrigDebugApp = mDebugApp;
6317 mOrigWaitForDebugger = mWaitForDebugger;
6318 }
6319 mDebugApp = packageName;
6320 mWaitForDebugger = waitForDebugger;
6321 mDebugTransient = !persistent;
6322 if (packageName != null) {
6323 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006324 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006325 Binder.restoreCallingIdentity(origId);
6326 }
6327 }
6328 }
6329
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006330 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6331 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6332 synchronized (this) {
6333 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6334 if (!isDebuggable) {
6335 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6336 throw new SecurityException("Process not debuggable: " + app.packageName);
6337 }
6338 }
6339 mProfileApp = processName;
6340 mProfileFile = profileFile;
6341 if (mProfileFd != null) {
6342 try {
6343 mProfileFd.close();
6344 } catch (IOException e) {
6345 }
6346 mProfileFd = null;
6347 }
6348 mProfileFd = profileFd;
6349 mProfileType = 0;
6350 mAutoStopProfiler = autoStopProfiler;
6351 }
6352 }
6353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006354 public void setAlwaysFinish(boolean enabled) {
6355 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6356 "setAlwaysFinish()");
6357
6358 Settings.System.putInt(
6359 mContext.getContentResolver(),
6360 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6361
6362 synchronized (this) {
6363 mAlwaysFinishActivities = enabled;
6364 }
6365 }
6366
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006367 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006368 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006369 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006370 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006371 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006372 }
6373 }
6374
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006375 public boolean isUserAMonkey() {
6376 // For now the fact that there is a controller implies
6377 // we have a monkey.
6378 synchronized (this) {
6379 return mController != null;
6380 }
6381 }
6382
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006383 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006384 synchronized (this) {
6385 mWatchers.register(watcher);
6386 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006387 }
6388
6389 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006390 synchronized (this) {
6391 mWatchers.unregister(watcher);
6392 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006393 }
6394
Jeff Sharkeya4620792011-05-20 15:29:23 -07006395 public void registerProcessObserver(IProcessObserver observer) {
6396 mProcessObservers.register(observer);
6397 }
6398
6399 public void unregisterProcessObserver(IProcessObserver observer) {
6400 mProcessObservers.unregister(observer);
6401 }
6402
Daniel Sandler69a48172010-06-23 16:29:36 -04006403 public void setImmersive(IBinder token, boolean immersive) {
6404 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006405 ActivityRecord r = mMainStack.isInStackLocked(token);
6406 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006407 throw new IllegalArgumentException();
6408 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006409 r.immersive = immersive;
6410 }
6411 }
6412
6413 public boolean isImmersive(IBinder token) {
6414 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006415 ActivityRecord r = mMainStack.isInStackLocked(token);
6416 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006417 throw new IllegalArgumentException();
6418 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006419 return r.immersive;
6420 }
6421 }
6422
6423 public boolean isTopActivityImmersive() {
6424 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006425 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006426 return (r != null) ? r.immersive : false;
6427 }
6428 }
6429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006430 public final void enterSafeMode() {
6431 synchronized(this) {
6432 // It only makes sense to do this before the system is ready
6433 // and started launching other packages.
6434 if (!mSystemReady) {
6435 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006436 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006437 } catch (RemoteException e) {
6438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006439 }
6440 }
6441 }
6442
Jeff Brownb09abc12011-01-13 21:08:27 -08006443 public final void showSafeModeOverlay() {
6444 View v = LayoutInflater.from(mContext).inflate(
6445 com.android.internal.R.layout.safe_mode, null);
6446 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6447 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6448 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6449 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6450 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6451 lp.format = v.getBackground().getOpacity();
6452 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6453 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6454 ((WindowManager)mContext.getSystemService(
6455 Context.WINDOW_SERVICE)).addView(v, lp);
6456 }
6457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006458 public void noteWakeupAlarm(IIntentSender sender) {
6459 if (!(sender instanceof PendingIntentRecord)) {
6460 return;
6461 }
6462 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6463 synchronized (stats) {
6464 if (mBatteryStatsService.isOnBattery()) {
6465 mBatteryStatsService.enforceCallingPermission();
6466 PendingIntentRecord rec = (PendingIntentRecord)sender;
6467 int MY_UID = Binder.getCallingUid();
6468 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6469 BatteryStatsImpl.Uid.Pkg pkg =
6470 stats.getPackageStatsLocked(uid, rec.key.packageName);
6471 pkg.incWakeupsLocked();
6472 }
6473 }
6474 }
6475
Dianne Hackborn64825172011-03-02 21:32:58 -08006476 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006477 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006478 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006479 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006480 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006481 // XXX Note: don't acquire main activity lock here, because the window
6482 // manager calls in with its locks held.
6483
6484 boolean killed = false;
6485 synchronized (mPidsSelfLocked) {
6486 int[] types = new int[pids.length];
6487 int worstType = 0;
6488 for (int i=0; i<pids.length; i++) {
6489 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6490 if (proc != null) {
6491 int type = proc.setAdj;
6492 types[i] = type;
6493 if (type > worstType) {
6494 worstType = type;
6495 }
6496 }
6497 }
6498
Dianne Hackborn64825172011-03-02 21:32:58 -08006499 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006500 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006501 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6502 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006503 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006504
6505 // If this is not a secure call, don't let it kill processes that
6506 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006507 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6508 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006509 }
6510
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006511 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006512 for (int i=0; i<pids.length; i++) {
6513 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6514 if (proc == null) {
6515 continue;
6516 }
6517 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006518 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006519 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006520 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6521 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006522 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006523 proc.killedBackground = true;
6524 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006525 }
6526 }
6527 }
6528 return killed;
6529 }
6530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006531 public final void startRunning(String pkg, String cls, String action,
6532 String data) {
6533 synchronized(this) {
6534 if (mStartRunning) {
6535 return;
6536 }
6537 mStartRunning = true;
6538 mTopComponent = pkg != null && cls != null
6539 ? new ComponentName(pkg, cls) : null;
6540 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6541 mTopData = data;
6542 if (!mSystemReady) {
6543 return;
6544 }
6545 }
6546
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006547 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006548 }
6549
6550 private void retrieveSettings() {
6551 final ContentResolver resolver = mContext.getContentResolver();
6552 String debugApp = Settings.System.getString(
6553 resolver, Settings.System.DEBUG_APP);
6554 boolean waitForDebugger = Settings.System.getInt(
6555 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6556 boolean alwaysFinishActivities = Settings.System.getInt(
6557 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6558
6559 Configuration configuration = new Configuration();
6560 Settings.System.getConfiguration(resolver, configuration);
6561
6562 synchronized (this) {
6563 mDebugApp = mOrigDebugApp = debugApp;
6564 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6565 mAlwaysFinishActivities = alwaysFinishActivities;
6566 // This happens before any activities are started, so we can
6567 // change mConfiguration in-place.
6568 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006569 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006570 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006571 }
6572 }
6573
6574 public boolean testIsSystemReady() {
6575 // no need to synchronize(this) just to read & return the value
6576 return mSystemReady;
6577 }
6578
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006579 private static File getCalledPreBootReceiversFile() {
6580 File dataDir = Environment.getDataDirectory();
6581 File systemDir = new File(dataDir, "system");
6582 File fname = new File(systemDir, "called_pre_boots.dat");
6583 return fname;
6584 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006585
6586 static final int LAST_DONE_VERSION = 10000;
6587
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006588 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6589 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6590 File file = getCalledPreBootReceiversFile();
6591 FileInputStream fis = null;
6592 try {
6593 fis = new FileInputStream(file);
6594 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006595 int fvers = dis.readInt();
6596 if (fvers == LAST_DONE_VERSION) {
6597 String vers = dis.readUTF();
6598 String codename = dis.readUTF();
6599 String build = dis.readUTF();
6600 if (android.os.Build.VERSION.RELEASE.equals(vers)
6601 && android.os.Build.VERSION.CODENAME.equals(codename)
6602 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6603 int num = dis.readInt();
6604 while (num > 0) {
6605 num--;
6606 String pkg = dis.readUTF();
6607 String cls = dis.readUTF();
6608 lastDoneReceivers.add(new ComponentName(pkg, cls));
6609 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006610 }
6611 }
6612 } catch (FileNotFoundException e) {
6613 } catch (IOException e) {
6614 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6615 } finally {
6616 if (fis != null) {
6617 try {
6618 fis.close();
6619 } catch (IOException e) {
6620 }
6621 }
6622 }
6623 return lastDoneReceivers;
6624 }
6625
6626 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6627 File file = getCalledPreBootReceiversFile();
6628 FileOutputStream fos = null;
6629 DataOutputStream dos = null;
6630 try {
6631 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6632 fos = new FileOutputStream(file);
6633 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006634 dos.writeInt(LAST_DONE_VERSION);
6635 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006636 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006637 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006638 dos.writeInt(list.size());
6639 for (int i=0; i<list.size(); i++) {
6640 dos.writeUTF(list.get(i).getPackageName());
6641 dos.writeUTF(list.get(i).getClassName());
6642 }
6643 } catch (IOException e) {
6644 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6645 file.delete();
6646 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006647 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006648 if (dos != null) {
6649 try {
6650 dos.close();
6651 } catch (IOException e) {
6652 // TODO Auto-generated catch block
6653 e.printStackTrace();
6654 }
6655 }
6656 }
6657 }
6658
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006659 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006660 synchronized(this) {
6661 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006662 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663 return;
6664 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006665
6666 // Check to see if there are any update receivers to run.
6667 if (!mDidUpdate) {
6668 if (mWaitingUpdate) {
6669 return;
6670 }
6671 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6672 List<ResolveInfo> ris = null;
6673 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006674 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006675 intent, null, 0);
6676 } catch (RemoteException e) {
6677 }
6678 if (ris != null) {
6679 for (int i=ris.size()-1; i>=0; i--) {
6680 if ((ris.get(i).activityInfo.applicationInfo.flags
6681 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6682 ris.remove(i);
6683 }
6684 }
6685 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006686
6687 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6688
6689 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006690 for (int i=0; i<ris.size(); i++) {
6691 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006692 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6693 if (lastDoneReceivers.contains(comp)) {
6694 ris.remove(i);
6695 i--;
6696 }
6697 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006698
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006699 for (int i=0; i<ris.size(); i++) {
6700 ActivityInfo ai = ris.get(i).activityInfo;
6701 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6702 doneReceivers.add(comp);
6703 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006704 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006705 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006706 finisher = new IIntentReceiver.Stub() {
6707 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006708 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006709 boolean sticky) {
6710 // The raw IIntentReceiver interface is called
6711 // with the AM lock held, so redispatch to
6712 // execute our code without the lock.
6713 mHandler.post(new Runnable() {
6714 public void run() {
6715 synchronized (ActivityManagerService.this) {
6716 mDidUpdate = true;
6717 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006718 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006719 showBootMessage(mContext.getText(
6720 R.string.android_upgrading_complete),
6721 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006722 systemReady(goingCallback);
6723 }
6724 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006725 }
6726 };
6727 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006728 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006729 broadcastIntentLocked(null, null, intent, null, finisher,
6730 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006731 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006732 mWaitingUpdate = true;
6733 }
6734 }
6735 }
6736 if (mWaitingUpdate) {
6737 return;
6738 }
6739 mDidUpdate = true;
6740 }
6741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006742 mSystemReady = true;
6743 if (!mStartRunning) {
6744 return;
6745 }
6746 }
6747
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006748 ArrayList<ProcessRecord> procsToKill = null;
6749 synchronized(mPidsSelfLocked) {
6750 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6751 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6752 if (!isAllowedWhileBooting(proc.info)){
6753 if (procsToKill == null) {
6754 procsToKill = new ArrayList<ProcessRecord>();
6755 }
6756 procsToKill.add(proc);
6757 }
6758 }
6759 }
6760
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006761 synchronized(this) {
6762 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006763 for (int i=procsToKill.size()-1; i>=0; i--) {
6764 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006765 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006766 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006767 }
6768 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006769
6770 // Now that we have cleaned up any update processes, we
6771 // are ready to start launching real processes and know that
6772 // we won't trample on them any more.
6773 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006774 }
6775
Joe Onorato8a9b2202010-02-26 18:56:32 -08006776 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006777 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006778 SystemClock.uptimeMillis());
6779
6780 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006781 // Make sure we have no pre-ready processes sitting around.
6782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006783 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6784 ResolveInfo ri = mContext.getPackageManager()
6785 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006786 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006787 CharSequence errorMsg = null;
6788 if (ri != null) {
6789 ActivityInfo ai = ri.activityInfo;
6790 ApplicationInfo app = ai.applicationInfo;
6791 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6792 mTopAction = Intent.ACTION_FACTORY_TEST;
6793 mTopData = null;
6794 mTopComponent = new ComponentName(app.packageName,
6795 ai.name);
6796 } else {
6797 errorMsg = mContext.getResources().getText(
6798 com.android.internal.R.string.factorytest_not_system);
6799 }
6800 } else {
6801 errorMsg = mContext.getResources().getText(
6802 com.android.internal.R.string.factorytest_no_action);
6803 }
6804 if (errorMsg != null) {
6805 mTopAction = null;
6806 mTopData = null;
6807 mTopComponent = null;
6808 Message msg = Message.obtain();
6809 msg.what = SHOW_FACTORY_ERROR_MSG;
6810 msg.getData().putCharSequence("msg", errorMsg);
6811 mHandler.sendMessage(msg);
6812 }
6813 }
6814 }
6815
6816 retrieveSettings();
6817
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006818 if (goingCallback != null) goingCallback.run();
6819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006820 synchronized (this) {
6821 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6822 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006823 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006824 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006825 if (apps != null) {
6826 int N = apps.size();
6827 int i;
6828 for (i=0; i<N; i++) {
6829 ApplicationInfo info
6830 = (ApplicationInfo)apps.get(i);
6831 if (info != null &&
6832 !info.packageName.equals("android")) {
6833 addAppLocked(info);
6834 }
6835 }
6836 }
6837 } catch (RemoteException ex) {
6838 // pm is in same process, this will never happen.
6839 }
6840 }
6841
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006842 // Start up initial activity.
6843 mBooting = true;
6844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006845 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006846 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006847 Message msg = Message.obtain();
6848 msg.what = SHOW_UID_ERROR_MSG;
6849 mHandler.sendMessage(msg);
6850 }
6851 } catch (RemoteException e) {
6852 }
6853
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006854 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006855 }
6856 }
6857
Dan Egnorb7f03672009-12-09 16:22:32 -08006858 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006859 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006860 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006861 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006862 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006863 startAppProblemLocked(app);
6864 app.stopFreezingAllLocked();
6865 return handleAppCrashLocked(app);
6866 }
6867
Dan Egnorb7f03672009-12-09 16:22:32 -08006868 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006869 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006870 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006871 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006872 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6873 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006874 startAppProblemLocked(app);
6875 app.stopFreezingAllLocked();
6876 }
6877
6878 /**
6879 * Generate a process error record, suitable for attachment to a ProcessRecord.
6880 *
6881 * @param app The ProcessRecord in which the error occurred.
6882 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6883 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006884 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006885 * @param shortMsg Short message describing the crash.
6886 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006887 * @param stackTrace Full crash stack trace, may be null.
6888 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006889 * @return Returns a fully-formed AppErrorStateInfo record.
6890 */
6891 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006892 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006893 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006895 report.condition = condition;
6896 report.processName = app.processName;
6897 report.pid = app.pid;
6898 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006899 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006900 report.shortMsg = shortMsg;
6901 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006902 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006903
6904 return report;
6905 }
6906
Dan Egnor42471dd2010-01-07 17:25:22 -08006907 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006908 synchronized (this) {
6909 app.crashing = false;
6910 app.crashingReport = null;
6911 app.notResponding = false;
6912 app.notRespondingReport = null;
6913 if (app.anrDialog == fromDialog) {
6914 app.anrDialog = null;
6915 }
6916 if (app.waitDialog == fromDialog) {
6917 app.waitDialog = null;
6918 }
6919 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006920 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006921 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006922 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6923 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006924 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006925 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006926 }
6927 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006928
Dan Egnorb7f03672009-12-09 16:22:32 -08006929 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006930 long now = SystemClock.uptimeMillis();
6931
6932 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6933 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006934 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006935 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006936 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006937 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006938 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006939 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006940 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6941 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006942 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006943 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006944 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006945 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006946 }
6947 }
6948 if (!app.persistent) {
6949 // We don't want to start this process again until the user
6950 // explicitly does so... but for persistent process, we really
6951 // need to keep it running. If a persistent process is actually
6952 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006953 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006954 app.info.processName);
6955 mBadProcesses.put(app.info.processName, app.info.uid, now);
6956 app.bad = true;
6957 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6958 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006959 // Don't let services in this process be restarted and potentially
6960 // annoy the user repeatedly. Unless it is persistent, since those
6961 // processes run critical code.
6962 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006963 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006964 return false;
6965 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006966 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006967 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006968 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006969 if (r.app == app) {
6970 // If the top running activity is from this crashing
6971 // process, then terminate it to avoid getting in a loop.
6972 Slog.w(TAG, " Force finishing activity "
6973 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006974 int index = mMainStack.indexOfTokenLocked(r);
6975 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006976 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006977 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006978 // stopped, to avoid a situation where one will get
6979 // re-start our crashing activity once it gets resumed again.
6980 index--;
6981 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006982 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006983 if (r.state == ActivityState.RESUMED
6984 || r.state == ActivityState.PAUSING
6985 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006986 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006987 Slog.w(TAG, " Force finishing activity "
6988 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006989 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006990 Activity.RESULT_CANCELED, null, "crashed");
6991 }
6992 }
6993 }
6994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006995 }
6996
6997 // Bump up the crash count of any services currently running in the proc.
6998 if (app.services.size() != 0) {
6999 // Any services running in the application need to be placed
7000 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007001 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007002 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007003 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007004 sr.crashCount++;
7005 }
7006 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007007
7008 // If the crashing process is what we consider to be the "home process" and it has been
7009 // replaced by a third-party app, clear the package preferred activities from packages
7010 // with a home activity running in the process to prevent a repeatedly crashing app
7011 // from blocking the user to manually clear the list.
7012 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7013 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7014 Iterator it = mHomeProcess.activities.iterator();
7015 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007016 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007017 if (r.isHomeActivity) {
7018 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7019 try {
7020 ActivityThread.getPackageManager()
7021 .clearPackagePreferredActivities(r.packageName);
7022 } catch (RemoteException c) {
7023 // pm is in same process, this will never happen.
7024 }
7025 }
7026 }
7027 }
7028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007029 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7030 return true;
7031 }
7032
7033 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007034 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7035 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007036 skipCurrentReceiverLocked(app);
7037 }
7038
7039 void skipCurrentReceiverLocked(ProcessRecord app) {
7040 boolean reschedule = false;
7041 BroadcastRecord r = app.curReceiver;
7042 if (r != null) {
7043 // The current broadcast is waiting for this app's receiver
7044 // to be finished. Looks like that's not going to happen, so
7045 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007046 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007047 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7048 r.resultExtras, r.resultAbort, true);
7049 reschedule = true;
7050 }
7051 r = mPendingBroadcast;
7052 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007053 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007054 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007055 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007056 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7057 r.resultExtras, r.resultAbort, true);
7058 reschedule = true;
7059 }
7060 if (reschedule) {
7061 scheduleBroadcastsLocked();
7062 }
7063 }
7064
Dan Egnor60d87622009-12-16 16:32:58 -08007065 /**
7066 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7067 * The application process will exit immediately after this call returns.
7068 * @param app object of the crashing app, null for the system server
7069 * @param crashInfo describing the exception
7070 */
7071 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007072 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08007073
7074 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7075 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007076 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007077 crashInfo.exceptionClassName,
7078 crashInfo.exceptionMessage,
7079 crashInfo.throwFileName,
7080 crashInfo.throwLineNumber);
7081
Dan Egnor42471dd2010-01-07 17:25:22 -08007082 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007083
7084 crashApplication(r, crashInfo);
7085 }
7086
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007087 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007088 IBinder app,
7089 int violationMask,
7090 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007091 ProcessRecord r = findAppProcess(app, "StrictMode");
7092 if (r == null) {
7093 return;
7094 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007095
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007096 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007097 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007098 boolean logIt = true;
7099 synchronized (mAlreadyLoggedViolatedStacks) {
7100 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7101 logIt = false;
7102 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007103 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007104 // the relative pain numbers, without logging all
7105 // the stack traces repeatedly. We'd want to do
7106 // likewise in the client code, which also does
7107 // dup suppression, before the Binder call.
7108 } else {
7109 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7110 mAlreadyLoggedViolatedStacks.clear();
7111 }
7112 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7113 }
7114 }
7115 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007116 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007117 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007118 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007119
7120 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7121 AppErrorResult result = new AppErrorResult();
7122 synchronized (this) {
7123 final long origId = Binder.clearCallingIdentity();
7124
7125 Message msg = Message.obtain();
7126 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7127 HashMap<String, Object> data = new HashMap<String, Object>();
7128 data.put("result", result);
7129 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007130 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007131 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007132 msg.obj = data;
7133 mHandler.sendMessage(msg);
7134
7135 Binder.restoreCallingIdentity(origId);
7136 }
7137 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007138 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007139 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007140 }
7141
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007142 // Depending on the policy in effect, there could be a bunch of
7143 // these in quick succession so we try to batch these together to
7144 // minimize disk writes, number of dropbox entries, and maximize
7145 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007146 private void logStrictModeViolationToDropBox(
7147 ProcessRecord process,
7148 StrictMode.ViolationInfo info) {
7149 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007150 return;
7151 }
7152 final boolean isSystemApp = process == null ||
7153 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7154 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7155 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7156 final DropBoxManager dbox = (DropBoxManager)
7157 mContext.getSystemService(Context.DROPBOX_SERVICE);
7158
7159 // Exit early if the dropbox isn't configured to accept this report type.
7160 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7161
7162 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007163 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007164 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7165 synchronized (sb) {
7166 bufferWasEmpty = sb.length() == 0;
7167 appendDropBoxProcessHeaders(process, sb);
7168 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7169 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007170 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7171 if (info.violationNumThisLoop != 0) {
7172 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7173 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007174 if (info.numAnimationsRunning != 0) {
7175 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7176 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007177 if (info.broadcastIntentAction != null) {
7178 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7179 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007180 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007181 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007182 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007183 if (info.numInstances != -1) {
7184 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7185 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007186 if (info.tags != null) {
7187 for (String tag : info.tags) {
7188 sb.append("Span-Tag: ").append(tag).append("\n");
7189 }
7190 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007191 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007192 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7193 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007194 }
7195 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007196
7197 // Only buffer up to ~64k. Various logging bits truncate
7198 // things at 128k.
7199 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007200 }
7201
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007202 // Flush immediately if the buffer's grown too large, or this
7203 // is a non-system app. Non-system apps are isolated with a
7204 // different tag & policy and not batched.
7205 //
7206 // Batching is useful during internal testing with
7207 // StrictMode settings turned up high. Without batching,
7208 // thousands of separate files could be created on boot.
7209 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007210 new Thread("Error dump: " + dropboxTag) {
7211 @Override
7212 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007213 String report;
7214 synchronized (sb) {
7215 report = sb.toString();
7216 sb.delete(0, sb.length());
7217 sb.trimToSize();
7218 }
7219 if (report.length() != 0) {
7220 dbox.addText(dropboxTag, report);
7221 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007222 }
7223 }.start();
7224 return;
7225 }
7226
7227 // System app batching:
7228 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007229 // An existing dropbox-writing thread is outstanding, so
7230 // we don't need to start it up. The existing thread will
7231 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007232 return;
7233 }
7234
7235 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7236 // (After this point, we shouldn't access AMS internal data structures.)
7237 new Thread("Error dump: " + dropboxTag) {
7238 @Override
7239 public void run() {
7240 // 5 second sleep to let stacks arrive and be batched together
7241 try {
7242 Thread.sleep(5000); // 5 seconds
7243 } catch (InterruptedException e) {}
7244
7245 String errorReport;
7246 synchronized (mStrictModeBuffer) {
7247 errorReport = mStrictModeBuffer.toString();
7248 if (errorReport.length() == 0) {
7249 return;
7250 }
7251 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7252 mStrictModeBuffer.trimToSize();
7253 }
7254 dbox.addText(dropboxTag, errorReport);
7255 }
7256 }.start();
7257 }
7258
Dan Egnor60d87622009-12-16 16:32:58 -08007259 /**
7260 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7261 * @param app object of the crashing app, null for the system server
7262 * @param tag reported by the caller
7263 * @param crashInfo describing the context of the error
7264 * @return true if the process should exit immediately (WTF is fatal)
7265 */
7266 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007267 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007268 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007269
7270 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7271 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007272 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007273 tag, crashInfo.exceptionMessage);
7274
Dan Egnor42471dd2010-01-07 17:25:22 -08007275 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007276
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007277 if (r != null && r.pid != Process.myPid() &&
7278 Settings.Secure.getInt(mContext.getContentResolver(),
7279 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007280 crashApplication(r, crashInfo);
7281 return true;
7282 } else {
7283 return false;
7284 }
7285 }
7286
7287 /**
7288 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7289 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7290 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007291 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007292 if (app == null) {
7293 return null;
7294 }
7295
7296 synchronized (this) {
7297 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7298 final int NA = apps.size();
7299 for (int ia=0; ia<NA; ia++) {
7300 ProcessRecord p = apps.valueAt(ia);
7301 if (p.thread != null && p.thread.asBinder() == app) {
7302 return p;
7303 }
7304 }
7305 }
7306
Dianne Hackborncb44d962011-03-10 17:02:27 -08007307 Slog.w(TAG, "Can't find mystery application for " + reason
7308 + " from pid=" + Binder.getCallingPid()
7309 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007310 return null;
7311 }
7312 }
7313
7314 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007315 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7316 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007317 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007318 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007319 // Watchdog thread ends up invoking this function (with
7320 // a null ProcessRecord) to add the stack file to dropbox.
7321 // Do not acquire a lock on this (am) in such cases, as it
7322 // could cause a potential deadlock, if and when watchdog
7323 // is invoked due to unavailability of lock on am and it
7324 // would prevent watchdog from killing system_server.
7325 if (process == null) {
7326 sb.append("Process: system_server\n");
7327 return;
7328 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007329 // Note: ProcessRecord 'process' is guarded by the service
7330 // instance. (notably process.pkgList, which could otherwise change
7331 // concurrently during execution of this method)
7332 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007333 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007334 sb.append("Process: system_server\n");
7335 } else {
7336 sb.append("Process: ").append(process.processName).append("\n");
7337 }
Dan Egnora455d192010-03-12 08:52:28 -08007338 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007339 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007340 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7341 for (String pkg : process.pkgList) {
7342 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007343 try {
Dan Egnora455d192010-03-12 08:52:28 -08007344 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7345 if (pi != null) {
7346 sb.append(" v").append(pi.versionCode);
7347 if (pi.versionName != null) {
7348 sb.append(" (").append(pi.versionName).append(")");
7349 }
7350 }
7351 } catch (RemoteException e) {
7352 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007353 }
Dan Egnora455d192010-03-12 08:52:28 -08007354 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007355 }
Dan Egnora455d192010-03-12 08:52:28 -08007356 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007357 }
7358
7359 private static String processClass(ProcessRecord process) {
7360 if (process == null || process.pid == MY_PID) {
7361 return "system_server";
7362 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7363 return "system_app";
7364 } else {
7365 return "data_app";
7366 }
7367 }
7368
7369 /**
7370 * Write a description of an error (crash, WTF, ANR) to the drop box.
7371 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7372 * @param process which caused the error, null means the system server
7373 * @param activity which triggered the error, null if unknown
7374 * @param parent activity related to the error, null if unknown
7375 * @param subject line related to the error, null if absent
7376 * @param report in long form describing the error, null if absent
7377 * @param logFile to include in the report, null if none
7378 * @param crashInfo giving an application stack trace, null if absent
7379 */
7380 public void addErrorToDropBox(String eventType,
7381 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7382 final String report, final File logFile,
7383 final ApplicationErrorReport.CrashInfo crashInfo) {
7384 // NOTE -- this must never acquire the ActivityManagerService lock,
7385 // otherwise the watchdog may be prevented from resetting the system.
7386
7387 final String dropboxTag = processClass(process) + "_" + eventType;
7388 final DropBoxManager dbox = (DropBoxManager)
7389 mContext.getSystemService(Context.DROPBOX_SERVICE);
7390
7391 // Exit early if the dropbox isn't configured to accept this report type.
7392 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7393
7394 final StringBuilder sb = new StringBuilder(1024);
7395 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007396 if (activity != null) {
7397 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7398 }
7399 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7400 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7401 }
7402 if (parent != null && parent != activity) {
7403 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7404 }
7405 if (subject != null) {
7406 sb.append("Subject: ").append(subject).append("\n");
7407 }
7408 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007409 if (Debug.isDebuggerConnected()) {
7410 sb.append("Debugger: Connected\n");
7411 }
Dan Egnora455d192010-03-12 08:52:28 -08007412 sb.append("\n");
7413
7414 // Do the rest in a worker thread to avoid blocking the caller on I/O
7415 // (After this point, we shouldn't access AMS internal data structures.)
7416 Thread worker = new Thread("Error dump: " + dropboxTag) {
7417 @Override
7418 public void run() {
7419 if (report != null) {
7420 sb.append(report);
7421 }
7422 if (logFile != null) {
7423 try {
7424 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7425 } catch (IOException e) {
7426 Slog.e(TAG, "Error reading " + logFile, e);
7427 }
7428 }
7429 if (crashInfo != null && crashInfo.stackTrace != null) {
7430 sb.append(crashInfo.stackTrace);
7431 }
7432
7433 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7434 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7435 if (lines > 0) {
7436 sb.append("\n");
7437
7438 // Merge several logcat streams, and take the last N lines
7439 InputStreamReader input = null;
7440 try {
7441 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7442 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7443 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7444
7445 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7446 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7447 input = new InputStreamReader(logcat.getInputStream());
7448
7449 int num;
7450 char[] buf = new char[8192];
7451 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7452 } catch (IOException e) {
7453 Slog.e(TAG, "Error running logcat", e);
7454 } finally {
7455 if (input != null) try { input.close(); } catch (IOException e) {}
7456 }
7457 }
7458
7459 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007460 }
Dan Egnora455d192010-03-12 08:52:28 -08007461 };
7462
7463 if (process == null || process.pid == MY_PID) {
7464 worker.run(); // We may be about to die -- need to run this synchronously
7465 } else {
7466 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007467 }
7468 }
7469
7470 /**
7471 * Bring up the "unexpected error" dialog box for a crashing app.
7472 * Deal with edge cases (intercepts from instrumented applications,
7473 * ActivityController, error intent receivers, that sort of thing).
7474 * @param r the application crashing
7475 * @param crashInfo describing the failure
7476 */
7477 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007478 long timeMillis = System.currentTimeMillis();
7479 String shortMsg = crashInfo.exceptionClassName;
7480 String longMsg = crashInfo.exceptionMessage;
7481 String stackTrace = crashInfo.stackTrace;
7482 if (shortMsg != null && longMsg != null) {
7483 longMsg = shortMsg + ": " + longMsg;
7484 } else if (shortMsg != null) {
7485 longMsg = shortMsg;
7486 }
7487
Dan Egnor60d87622009-12-16 16:32:58 -08007488 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007489 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007490 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007491 try {
7492 String name = r != null ? r.processName : null;
7493 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007494 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007495 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007496 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007497 + " at watcher's request");
7498 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007499 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007500 }
7501 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007502 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007503 }
7504 }
7505
7506 final long origId = Binder.clearCallingIdentity();
7507
7508 // If this process is running instrumentation, finish it.
7509 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007510 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007511 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007512 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7513 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007514 Bundle info = new Bundle();
7515 info.putString("shortMsg", shortMsg);
7516 info.putString("longMsg", longMsg);
7517 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7518 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007519 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007520 }
7521
Dan Egnor60d87622009-12-16 16:32:58 -08007522 // If we can't identify the process or it's already exceeded its crash quota,
7523 // quit right away without showing a crash dialog.
7524 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007525 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007526 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 }
7528
7529 Message msg = Message.obtain();
7530 msg.what = SHOW_ERROR_MSG;
7531 HashMap data = new HashMap();
7532 data.put("result", result);
7533 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007534 msg.obj = data;
7535 mHandler.sendMessage(msg);
7536
7537 Binder.restoreCallingIdentity(origId);
7538 }
7539
7540 int res = result.get();
7541
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007542 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007543 synchronized (this) {
7544 if (r != null) {
7545 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7546 SystemClock.uptimeMillis());
7547 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007548 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007549 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007550 }
7551 }
7552
7553 if (appErrorIntent != null) {
7554 try {
7555 mContext.startActivity(appErrorIntent);
7556 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007557 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007559 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007560 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007561
7562 Intent createAppErrorIntentLocked(ProcessRecord r,
7563 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7564 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007565 if (report == null) {
7566 return null;
7567 }
7568 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7569 result.setComponent(r.errorReportReceiver);
7570 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7571 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7572 return result;
7573 }
7574
Dan Egnorb7f03672009-12-09 16:22:32 -08007575 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7576 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007577 if (r.errorReportReceiver == null) {
7578 return null;
7579 }
7580
7581 if (!r.crashing && !r.notResponding) {
7582 return null;
7583 }
7584
Dan Egnorb7f03672009-12-09 16:22:32 -08007585 ApplicationErrorReport report = new ApplicationErrorReport();
7586 report.packageName = r.info.packageName;
7587 report.installerPackageName = r.errorReportReceiver.getPackageName();
7588 report.processName = r.processName;
7589 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007590 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007591
Dan Egnorb7f03672009-12-09 16:22:32 -08007592 if (r.crashing) {
7593 report.type = ApplicationErrorReport.TYPE_CRASH;
7594 report.crashInfo = crashInfo;
7595 } else if (r.notResponding) {
7596 report.type = ApplicationErrorReport.TYPE_ANR;
7597 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007598
Dan Egnorb7f03672009-12-09 16:22:32 -08007599 report.anrInfo.activity = r.notRespondingReport.tag;
7600 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7601 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007602 }
7603
Dan Egnorb7f03672009-12-09 16:22:32 -08007604 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007605 }
7606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007607 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7608 // assume our apps are happy - lazy create the list
7609 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7610
7611 synchronized (this) {
7612
7613 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007614 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7615 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007616 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7617 // This one's in trouble, so we'll generate a report for it
7618 // crashes are higher priority (in case there's a crash *and* an anr)
7619 ActivityManager.ProcessErrorStateInfo report = null;
7620 if (app.crashing) {
7621 report = app.crashingReport;
7622 } else if (app.notResponding) {
7623 report = app.notRespondingReport;
7624 }
7625
7626 if (report != null) {
7627 if (errList == null) {
7628 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7629 }
7630 errList.add(report);
7631 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007632 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007633 " crashing = " + app.crashing +
7634 " notResponding = " + app.notResponding);
7635 }
7636 }
7637 }
7638 }
7639
7640 return errList;
7641 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007642
7643 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
7644 if (adj >= ProcessList.EMPTY_APP_ADJ) {
7645 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7646 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
7647 if (currApp != null) {
7648 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7649 }
7650 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7651 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7652 if (currApp != null) {
7653 currApp.lru = 0;
7654 }
7655 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7656 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
7657 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7658 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7659 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7660 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7661 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7662 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7663 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7664 } else {
7665 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7666 }
7667 }
7668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007669 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7670 // Lazy instantiation of list
7671 List<ActivityManager.RunningAppProcessInfo> runList = null;
7672 synchronized (this) {
7673 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007674 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7675 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007676 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7677 // Generate process state info for running application
7678 ActivityManager.RunningAppProcessInfo currApp =
7679 new ActivityManager.RunningAppProcessInfo(app.processName,
7680 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007681 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007682 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007683 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007684 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007685 if (app.persistent) {
7686 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7687 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007688 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007689 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007690 currApp.importanceReasonCode = app.adjTypeCode;
7691 if (app.adjSource instanceof ProcessRecord) {
7692 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007693 currApp.importanceReasonImportance = oomAdjToImportance(
7694 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007695 } else if (app.adjSource instanceof ActivityRecord) {
7696 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007697 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7698 }
7699 if (app.adjTarget instanceof ComponentName) {
7700 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7701 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007702 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007703 // + " lru=" + currApp.lru);
7704 if (runList == null) {
7705 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7706 }
7707 runList.add(currApp);
7708 }
7709 }
7710 }
7711 return runList;
7712 }
7713
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007714 public List<ApplicationInfo> getRunningExternalApplications() {
7715 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7716 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7717 if (runningApps != null && runningApps.size() > 0) {
7718 Set<String> extList = new HashSet<String>();
7719 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7720 if (app.pkgList != null) {
7721 for (String pkg : app.pkgList) {
7722 extList.add(pkg);
7723 }
7724 }
7725 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007726 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007727 for (String pkg : extList) {
7728 try {
7729 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7730 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7731 retList.add(info);
7732 }
7733 } catch (RemoteException e) {
7734 }
7735 }
7736 }
7737 return retList;
7738 }
7739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007740 @Override
7741 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007742 if (checkCallingPermission(android.Manifest.permission.DUMP)
7743 != PackageManager.PERMISSION_GRANTED) {
7744 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7745 + Binder.getCallingPid()
7746 + ", uid=" + Binder.getCallingUid()
7747 + " without permission "
7748 + android.Manifest.permission.DUMP);
7749 return;
7750 }
7751
7752 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007753 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007754
7755 int opti = 0;
7756 while (opti < args.length) {
7757 String opt = args[opti];
7758 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7759 break;
7760 }
7761 opti++;
7762 if ("-a".equals(opt)) {
7763 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007764 } else if ("-c".equals(opt)) {
7765 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007766 } else if ("-h".equals(opt)) {
7767 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007768 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007769 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007770 pw.println(" a[ctivities]: activity stack state");
7771 pw.println(" b[roadcasts]: broadcast state");
7772 pw.println(" i[ntents]: pending intent state");
7773 pw.println(" p[rocesses]: process state");
7774 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007775 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7776 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007777 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007778 pw.println(" all: dump all activities");
7779 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007780 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007781 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7782 pw.println(" a partial substring in a component name, a");
7783 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007784 pw.println(" -a: include all available server state.");
7785 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007786 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007787 } else {
7788 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007789 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007790 }
7791
7792 // Is the caller requesting to dump a particular piece of data?
7793 if (opti < args.length) {
7794 String cmd = args[opti];
7795 opti++;
7796 if ("activities".equals(cmd) || "a".equals(cmd)) {
7797 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007798 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007799 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007800 return;
7801 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7802 synchronized (this) {
7803 dumpBroadcastsLocked(fd, pw, args, opti, true);
7804 }
7805 return;
7806 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7807 synchronized (this) {
7808 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7809 }
7810 return;
7811 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7812 synchronized (this) {
7813 dumpProcessesLocked(fd, pw, args, opti, true);
7814 }
7815 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007816 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7817 synchronized (this) {
7818 dumpOomLocked(fd, pw, args, opti, true);
7819 }
7820 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007821 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7822 synchronized (this) {
7823 dumpProvidersLocked(fd, pw, args, opti, true);
7824 }
7825 return;
7826 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007827 String[] newArgs;
7828 String name;
7829 if (opti >= args.length) {
7830 name = null;
7831 newArgs = EMPTY_STRING_ARRAY;
7832 } else {
7833 name = args[opti];
7834 opti++;
7835 newArgs = new String[args.length - opti];
7836 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7837 }
7838 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7839 pw.println("No services match: " + name);
7840 pw.println("Use -h for help.");
7841 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007842 return;
7843 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7844 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007845 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007846 }
7847 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007848 } else {
7849 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007850 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7851 pw.println("Bad activity command, or no activities match: " + cmd);
7852 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007853 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007854 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007855 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007856 }
7857
7858 // No piece of data specified, dump everything.
7859 synchronized (this) {
7860 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007861 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007862 if (needSep) {
7863 pw.println(" ");
7864 }
7865 if (dumpAll) {
7866 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007867 }
7868 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7869 if (needSep) {
7870 pw.println(" ");
7871 }
7872 if (dumpAll) {
7873 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007874 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007875 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007876 if (needSep) {
7877 pw.println(" ");
7878 }
7879 if (dumpAll) {
7880 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007881 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007882 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007883 if (needSep) {
7884 pw.println(" ");
7885 }
7886 if (dumpAll) {
7887 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007888 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007889 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007890 if (needSep) {
7891 pw.println(" ");
7892 }
7893 if (dumpAll) {
7894 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007895 }
7896 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7897 }
7898 }
7899
7900 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007901 int opti, boolean dumpAll, boolean dumpClient) {
7902 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7903 pw.println(" Main stack:");
7904 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007905 pw.println(" ");
7906 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007907 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007908 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007909 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007910 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007911 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7912 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007913 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007914 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007915 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007916 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007917 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7918 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007919 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007920 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7921 pw.println(" ");
7922 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007923 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7924 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007925 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007926 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007927 pw.println(" ");
7928 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007929 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7930 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007931 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007932
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007933 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007934 if (mMainStack.mPausingActivity != null) {
7935 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7936 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007937 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007938 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007939 if (dumpAll) {
7940 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7941 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07007942 pw.println(" mDismissKeyguardOnNextActivity: "
7943 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007944 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007945
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007946 if (mRecentTasks.size() > 0) {
7947 pw.println();
7948 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007949
7950 final int N = mRecentTasks.size();
7951 for (int i=0; i<N; i++) {
7952 TaskRecord tr = mRecentTasks.get(i);
7953 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7954 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007955 if (dumpAll) {
7956 mRecentTasks.get(i).dump(pw, " ");
7957 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007958 }
7959 }
7960
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007961 if (dumpAll) {
7962 pw.println(" ");
7963 pw.println(" mCurTask: " + mCurTask);
7964 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007965
7966 return true;
7967 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007968
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007969 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7970 int opti, boolean dumpAll) {
7971 boolean needSep = false;
7972 int numPers = 0;
7973
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007974 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7975
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007976 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007977 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7978 final int NA = procs.size();
7979 for (int ia=0; ia<NA; ia++) {
7980 if (!needSep) {
7981 pw.println(" All known processes:");
7982 needSep = true;
7983 }
7984 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007985 pw.print(r.persistent ? " *PERS*" : " *APP*");
7986 pw.print(" UID "); pw.print(procs.keyAt(ia));
7987 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007988 r.dump(pw, " ");
7989 if (r.persistent) {
7990 numPers++;
7991 }
7992 }
7993 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007994 }
7995
7996 if (mLruProcesses.size() > 0) {
7997 if (needSep) pw.println(" ");
7998 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007999 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008000 dumpProcessOomList(pw, this, mLruProcesses, " ",
8001 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008002 needSep = true;
8003 }
8004
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008005 if (dumpAll) {
8006 synchronized (mPidsSelfLocked) {
8007 if (mPidsSelfLocked.size() > 0) {
8008 if (needSep) pw.println(" ");
8009 needSep = true;
8010 pw.println(" PID mappings:");
8011 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8012 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8013 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8014 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008015 }
8016 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008017 }
8018
8019 if (mForegroundProcesses.size() > 0) {
8020 if (needSep) pw.println(" ");
8021 needSep = true;
8022 pw.println(" Foreground Processes:");
8023 for (int i=0; i<mForegroundProcesses.size(); i++) {
8024 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8025 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008026 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008027 }
8028
8029 if (mPersistentStartingProcesses.size() > 0) {
8030 if (needSep) pw.println(" ");
8031 needSep = true;
8032 pw.println(" Persisent processes that are starting:");
8033 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008034 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008036
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008037 if (mRemovedProcesses.size() > 0) {
8038 if (needSep) pw.println(" ");
8039 needSep = true;
8040 pw.println(" Processes that are being removed:");
8041 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008042 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008043 }
8044
8045 if (mProcessesOnHold.size() > 0) {
8046 if (needSep) pw.println(" ");
8047 needSep = true;
8048 pw.println(" Processes that are on old until the system is ready:");
8049 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008050 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008052
Dianne Hackborn287952c2010-09-22 22:34:31 -07008053 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008054
8055 if (mProcessCrashTimes.getMap().size() > 0) {
8056 if (needSep) pw.println(" ");
8057 needSep = true;
8058 pw.println(" Time since processes crashed:");
8059 long now = SystemClock.uptimeMillis();
8060 for (Map.Entry<String, SparseArray<Long>> procs
8061 : mProcessCrashTimes.getMap().entrySet()) {
8062 SparseArray<Long> uids = procs.getValue();
8063 final int N = uids.size();
8064 for (int i=0; i<N; i++) {
8065 pw.print(" Process "); pw.print(procs.getKey());
8066 pw.print(" uid "); pw.print(uids.keyAt(i));
8067 pw.print(": last crashed ");
8068 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008069 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008070 }
8071 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008072 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008073
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008074 if (mBadProcesses.getMap().size() > 0) {
8075 if (needSep) pw.println(" ");
8076 needSep = true;
8077 pw.println(" Bad processes:");
8078 for (Map.Entry<String, SparseArray<Long>> procs
8079 : mBadProcesses.getMap().entrySet()) {
8080 SparseArray<Long> uids = procs.getValue();
8081 final int N = uids.size();
8082 for (int i=0; i<N; i++) {
8083 pw.print(" Bad process "); pw.print(procs.getKey());
8084 pw.print(" uid "); pw.print(uids.keyAt(i));
8085 pw.print(": crashed at time ");
8086 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008087 }
8088 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008089 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008090
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008091 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008092 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008093 if (mHeavyWeightProcess != null) {
8094 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8095 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008096 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008097 if (dumpAll) {
8098 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008099 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008100 pw.println(" mScreenCompatPackages:");
8101 for (Map.Entry<String, Integer> entry
8102 : mCompatModePackages.getPackages().entrySet()) {
8103 String pkg = entry.getKey();
8104 int mode = entry.getValue();
8105 pw.print(" "); pw.print(pkg); pw.print(": ");
8106 pw.print(mode); pw.println();
8107 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008108 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008109 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008110 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8111 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8112 || mOrigWaitForDebugger) {
8113 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8114 + " mDebugTransient=" + mDebugTransient
8115 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8116 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008117 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8118 || mProfileFd != null) {
8119 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8120 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8121 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8122 + mAutoStopProfiler);
8123 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008124 if (mAlwaysFinishActivities || mController != null) {
8125 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8126 + " mController=" + mController);
8127 }
8128 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008129 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008130 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008131 + " mProcessesReady=" + mProcessesReady
8132 + " mSystemReady=" + mSystemReady);
8133 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008134 + " mBooted=" + mBooted
8135 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008136 pw.print(" mLastPowerCheckRealtime=");
8137 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8138 pw.println("");
8139 pw.print(" mLastPowerCheckUptime=");
8140 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8141 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008142 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8143 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008144 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008145 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008146
8147 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008148 }
8149
Dianne Hackborn287952c2010-09-22 22:34:31 -07008150 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8151 int opti, boolean needSep, boolean dumpAll) {
8152 if (mProcessesToGc.size() > 0) {
8153 if (needSep) pw.println(" ");
8154 needSep = true;
8155 pw.println(" Processes that are waiting to GC:");
8156 long now = SystemClock.uptimeMillis();
8157 for (int i=0; i<mProcessesToGc.size(); i++) {
8158 ProcessRecord proc = mProcessesToGc.get(i);
8159 pw.print(" Process "); pw.println(proc);
8160 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8161 pw.print(", last gced=");
8162 pw.print(now-proc.lastRequestedGc);
8163 pw.print(" ms ago, last lowMem=");
8164 pw.print(now-proc.lastLowMemory);
8165 pw.println(" ms ago");
8166
8167 }
8168 }
8169 return needSep;
8170 }
8171
8172 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8173 int opti, boolean dumpAll) {
8174 boolean needSep = false;
8175
8176 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008177 if (needSep) pw.println(" ");
8178 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008179 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008180 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8181 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
8182 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8183 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8184 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8185 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8186 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8187 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
8188 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8189 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8190 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008191
8192 if (needSep) pw.println(" ");
8193 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008194 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008195 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008196 "Proc", "PERS", true);
8197 needSep = true;
8198 }
8199
8200 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8201
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008202 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008203 pw.println(" mHomeProcess: " + mHomeProcess);
8204 if (mHeavyWeightProcess != null) {
8205 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8206 }
8207
8208 return true;
8209 }
8210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008211 /**
8212 * There are three ways to call this:
8213 * - no service specified: dump all the services
8214 * - a flattened component name that matched an existing service was specified as the
8215 * first arg: dump that one service
8216 * - the first arg isn't the flattened component name of an existing service:
8217 * dump all services whose component contains the first arg as a substring
8218 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008219 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8220 int opti, boolean dumpAll) {
8221 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008222
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008223 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008224 synchronized (this) {
8225 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008226 services.add(r1);
8227 }
8228 }
8229 } else {
8230 ComponentName componentName = name != null
8231 ? ComponentName.unflattenFromString(name) : null;
8232 int objectId = 0;
8233 if (componentName == null) {
8234 // Not a '/' separated full component name; maybe an object ID?
8235 try {
8236 objectId = Integer.parseInt(name, 16);
8237 name = null;
8238 componentName = null;
8239 } catch (RuntimeException e) {
8240 }
8241 }
8242
8243 synchronized (this) {
8244 for (ServiceRecord r1 : mServices.values()) {
8245 if (componentName != null) {
8246 if (r1.name.equals(componentName)) {
8247 services.add(r1);
8248 }
8249 } else if (name != null) {
8250 if (r1.name.flattenToString().contains(name)) {
8251 services.add(r1);
8252 }
8253 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008254 services.add(r1);
8255 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008256 }
8257 }
8258 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008259
8260 if (services.size() <= 0) {
8261 return false;
8262 }
8263
8264 boolean needSep = false;
8265 for (int i=0; i<services.size(); i++) {
8266 if (needSep) {
8267 pw.println();
8268 }
8269 needSep = true;
8270 dumpService("", fd, pw, services.get(i), args, dumpAll);
8271 }
8272 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008273 }
8274
8275 /**
8276 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8277 * there is a thread associated with the service.
8278 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008279 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8280 final ServiceRecord r, String[] args, boolean dumpAll) {
8281 String innerPrefix = prefix + " ";
8282 synchronized (this) {
8283 pw.print(prefix); pw.print("SERVICE ");
8284 pw.print(r.shortName); pw.print(" ");
8285 pw.print(Integer.toHexString(System.identityHashCode(r)));
8286 pw.print(" pid=");
8287 if (r.app != null) pw.println(r.app.pid);
8288 else pw.println("(not running)");
8289 if (dumpAll) {
8290 r.dump(pw, innerPrefix);
8291 }
8292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008293 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008294 pw.print(prefix); pw.println(" Client:");
8295 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008296 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008297 TransferPipe tp = new TransferPipe();
8298 try {
8299 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8300 tp.setBufferPrefix(prefix + " ");
8301 tp.go(fd);
8302 } finally {
8303 tp.kill();
8304 }
8305 } catch (IOException e) {
8306 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008307 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008308 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008309 }
8310 }
8311 }
8312
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008313 static class ItemMatcher {
8314 ArrayList<ComponentName> components;
8315 ArrayList<String> strings;
8316 ArrayList<Integer> objects;
8317 boolean all;
8318
8319 ItemMatcher() {
8320 all = true;
8321 }
8322
8323 void build(String name) {
8324 ComponentName componentName = ComponentName.unflattenFromString(name);
8325 if (componentName != null) {
8326 if (components == null) {
8327 components = new ArrayList<ComponentName>();
8328 }
8329 components.add(componentName);
8330 all = false;
8331 } else {
8332 int objectId = 0;
8333 // Not a '/' separated full component name; maybe an object ID?
8334 try {
8335 objectId = Integer.parseInt(name, 16);
8336 if (objects == null) {
8337 objects = new ArrayList<Integer>();
8338 }
8339 objects.add(objectId);
8340 all = false;
8341 } catch (RuntimeException e) {
8342 // Not an integer; just do string match.
8343 if (strings == null) {
8344 strings = new ArrayList<String>();
8345 }
8346 strings.add(name);
8347 all = false;
8348 }
8349 }
8350 }
8351
8352 int build(String[] args, int opti) {
8353 for (; opti<args.length; opti++) {
8354 String name = args[opti];
8355 if ("--".equals(name)) {
8356 return opti+1;
8357 }
8358 build(name);
8359 }
8360 return opti;
8361 }
8362
8363 boolean match(Object object, ComponentName comp) {
8364 if (all) {
8365 return true;
8366 }
8367 if (components != null) {
8368 for (int i=0; i<components.size(); i++) {
8369 if (components.get(i).equals(comp)) {
8370 return true;
8371 }
8372 }
8373 }
8374 if (objects != null) {
8375 for (int i=0; i<objects.size(); i++) {
8376 if (System.identityHashCode(object) == objects.get(i)) {
8377 return true;
8378 }
8379 }
8380 }
8381 if (strings != null) {
8382 String flat = comp.flattenToString();
8383 for (int i=0; i<strings.size(); i++) {
8384 if (flat.contains(strings.get(i))) {
8385 return true;
8386 }
8387 }
8388 }
8389 return false;
8390 }
8391 }
8392
Dianne Hackborn625ac272010-09-17 18:29:22 -07008393 /**
8394 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008395 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008396 * - the cmd arg isn't the flattened component name of an existing activity:
8397 * dump all activity whose component contains the cmd as a substring
8398 * - A hex number of the ActivityRecord object instance.
8399 */
8400 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8401 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008402 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008403
8404 if ("all".equals(name)) {
8405 synchronized (this) {
8406 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008407 activities.add(r1);
8408 }
8409 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008410 } else if ("top".equals(name)) {
8411 synchronized (this) {
8412 final int N = mMainStack.mHistory.size();
8413 if (N > 0) {
8414 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8415 }
8416 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008417 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008418 ItemMatcher matcher = new ItemMatcher();
8419 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008420
8421 synchronized (this) {
8422 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008423 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008424 activities.add(r1);
8425 }
8426 }
8427 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008428 }
8429
8430 if (activities.size() <= 0) {
8431 return false;
8432 }
8433
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008434 String[] newArgs = new String[args.length - opti];
8435 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8436
Dianne Hackborn30d71892010-12-11 10:37:55 -08008437 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008438 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008439 for (int i=activities.size()-1; i>=0; i--) {
8440 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008441 if (needSep) {
8442 pw.println();
8443 }
8444 needSep = true;
8445 synchronized (this) {
8446 if (lastTask != r.task) {
8447 lastTask = r.task;
8448 pw.print("TASK "); pw.print(lastTask.affinity);
8449 pw.print(" id="); pw.println(lastTask.taskId);
8450 if (dumpAll) {
8451 lastTask.dump(pw, " ");
8452 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008453 }
8454 }
8455 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008456 }
8457 return true;
8458 }
8459
8460 /**
8461 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8462 * there is a thread associated with the activity.
8463 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008464 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008465 final ActivityRecord r, String[] args, boolean dumpAll) {
8466 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008467 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008468 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8469 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8470 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008471 if (r.app != null) pw.println(r.app.pid);
8472 else pw.println("(not running)");
8473 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008474 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008475 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008476 }
8477 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008478 // flush anything that is already in the PrintWriter since the thread is going
8479 // to write to the file descriptor directly
8480 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008481 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008482 TransferPipe tp = new TransferPipe();
8483 try {
8484 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8485 innerPrefix, args);
8486 tp.go(fd);
8487 } finally {
8488 tp.kill();
8489 }
8490 } catch (IOException e) {
8491 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008492 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008493 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008494 }
8495 }
8496 }
8497
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008498 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8499 int opti, boolean dumpAll) {
8500 boolean needSep = false;
8501
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008502 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008503 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008504 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008505 pw.println(" Registered Receivers:");
8506 Iterator it = mRegisteredReceivers.values().iterator();
8507 while (it.hasNext()) {
8508 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008509 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008510 r.dump(pw, " ");
8511 }
8512 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008513
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008514 pw.println();
8515 pw.println(" Receiver Resolver Table:");
8516 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008517 needSep = true;
8518 }
8519
8520 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8521 || mPendingBroadcast != null) {
8522 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008523 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008524 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008525 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008526 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8527 pw.println(" Broadcast #" + i + ":");
8528 mParallelBroadcasts.get(i).dump(pw, " ");
8529 }
8530 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008531 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008532 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008533 }
8534 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8535 pw.println(" Serialized Broadcast #" + i + ":");
8536 mOrderedBroadcasts.get(i).dump(pw, " ");
8537 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008538 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008539 pw.println(" Pending broadcast:");
8540 if (mPendingBroadcast != null) {
8541 mPendingBroadcast.dump(pw, " ");
8542 } else {
8543 pw.println(" (null)");
8544 }
8545 needSep = true;
8546 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008547
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008548 if (needSep) {
8549 pw.println();
8550 }
8551 pw.println(" Historical broadcasts:");
8552 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8553 BroadcastRecord r = mBroadcastHistory[i];
8554 if (r == null) {
8555 break;
8556 }
8557 if (dumpAll) {
8558 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8559 r.dump(pw, " ");
8560 } else {
8561 if (i >= 50) {
8562 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008563 break;
8564 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008565 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008566 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008567 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008568 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008569
8570 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008571 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008572 pw.println(" Sticky broadcasts:");
8573 StringBuilder sb = new StringBuilder(128);
8574 for (Map.Entry<String, ArrayList<Intent>> ent
8575 : mStickyBroadcasts.entrySet()) {
8576 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008577 if (dumpAll) {
8578 pw.println(":");
8579 ArrayList<Intent> intents = ent.getValue();
8580 final int N = intents.size();
8581 for (int i=0; i<N; i++) {
8582 sb.setLength(0);
8583 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008584 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008585 pw.println(sb.toString());
8586 Bundle bundle = intents.get(i).getExtras();
8587 if (bundle != null) {
8588 pw.print(" ");
8589 pw.println(bundle.toString());
8590 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008591 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008592 } else {
8593 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008594 }
8595 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008596 needSep = true;
8597 }
8598
8599 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008600 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008601 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008602 pw.println(" mHandler:");
8603 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008604 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008605 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008606
8607 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008608 }
8609
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008610 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008611 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008612 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008613
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008614 ItemMatcher matcher = new ItemMatcher();
8615 matcher.build(args, opti);
8616
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008617 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8618 if (mServices.size() > 0) {
8619 pw.println(" Active services:");
8620 long nowReal = SystemClock.elapsedRealtime();
8621 Iterator<ServiceRecord> it = mServices.values().iterator();
8622 needSep = false;
8623 while (it.hasNext()) {
8624 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008625 if (!matcher.match(r, r.name)) {
8626 continue;
8627 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008628 if (needSep) {
8629 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008630 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008631 pw.print(" * "); pw.println(r);
8632 if (dumpAll) {
8633 r.dump(pw, " ");
8634 needSep = true;
8635 } else {
8636 pw.print(" app="); pw.println(r.app);
8637 pw.print(" created=");
8638 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8639 pw.print(" started="); pw.print(r.startRequested);
8640 pw.print(" connections="); pw.println(r.connections.size());
8641 }
8642 if (dumpClient && r.app != null && r.app.thread != null) {
8643 pw.println(" Client:");
8644 pw.flush();
8645 try {
8646 TransferPipe tp = new TransferPipe();
8647 try {
8648 r.app.thread.dumpService(
8649 tp.getWriteFd().getFileDescriptor(), r, args);
8650 tp.setBufferPrefix(" ");
8651 // Short timeout, since blocking here can
8652 // deadlock with the application.
8653 tp.go(fd, 2000);
8654 } finally {
8655 tp.kill();
8656 }
8657 } catch (IOException e) {
8658 pw.println(" Failure while dumping the service: " + e);
8659 } catch (RemoteException e) {
8660 pw.println(" Got a RemoteException while dumping the service");
8661 }
8662 needSep = true;
8663 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008664 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008665 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008667
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008668 if (mPendingServices.size() > 0) {
8669 if (needSep) pw.println(" ");
8670 pw.println(" Pending services:");
8671 for (int i=0; i<mPendingServices.size(); i++) {
8672 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008673 if (!matcher.match(r, r.name)) {
8674 continue;
8675 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008676 pw.print(" * Pending "); pw.println(r);
8677 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008678 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008679 needSep = true;
8680 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008681
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008682 if (mRestartingServices.size() > 0) {
8683 if (needSep) pw.println(" ");
8684 pw.println(" Restarting services:");
8685 for (int i=0; i<mRestartingServices.size(); i++) {
8686 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008687 if (!matcher.match(r, r.name)) {
8688 continue;
8689 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008690 pw.print(" * Restarting "); pw.println(r);
8691 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008692 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008693 needSep = true;
8694 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008695
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008696 if (mStoppingServices.size() > 0) {
8697 if (needSep) pw.println(" ");
8698 pw.println(" Stopping services:");
8699 for (int i=0; i<mStoppingServices.size(); i++) {
8700 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008701 if (!matcher.match(r, r.name)) {
8702 continue;
8703 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008704 pw.print(" * Stopping "); pw.println(r);
8705 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008706 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008707 needSep = true;
8708 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008709
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008710 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008711 if (mServiceConnections.size() > 0) {
8712 if (needSep) pw.println(" ");
8713 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008714 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008715 = mServiceConnections.values().iterator();
8716 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008717 ArrayList<ConnectionRecord> r = it.next();
8718 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008719 ConnectionRecord cr = r.get(i);
8720 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8721 continue;
8722 }
8723 pw.print(" * "); pw.println(cr);
8724 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008725 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008726 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008727 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008728 }
8729 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008730
8731 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008732 }
8733
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008734 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8735 int opti, boolean dumpAll) {
8736 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008737
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008738 ItemMatcher matcher = new ItemMatcher();
8739 matcher.build(args, opti);
8740
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008741 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8742 if (mProvidersByClass.size() > 0) {
8743 if (needSep) pw.println(" ");
8744 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008745 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008746 = mProvidersByClass.entrySet().iterator();
8747 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008748 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008749 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008750 ComponentName comp = e.getKey();
8751 String cls = comp.getClassName();
8752 int end = cls.lastIndexOf('.');
8753 if (end > 0 && end < (cls.length()-2)) {
8754 cls = cls.substring(end+1);
8755 }
8756 if (!matcher.match(r, comp)) {
8757 continue;
8758 }
8759 pw.print(" * "); pw.print(cls); pw.print(" (");
8760 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008761 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008762 pw.println();
8763 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008764 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008765 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008766 if (r.proc != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008767 pw.println(":");
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008768 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008769 } else {
8770 pw.println();
8771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008772 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008773 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008774 needSep = true;
8775 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008776
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008777 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008778 if (mProvidersByName.size() > 0) {
8779 pw.println(" ");
8780 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008781 Iterator<Map.Entry<String, ContentProviderRecord>> it
8782 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008783 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008784 Map.Entry<String, ContentProviderRecord> e = it.next();
8785 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008786 if (!matcher.match(r, r.name)) {
8787 continue;
8788 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008789 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8790 pw.println(r);
8791 }
8792 needSep = true;
8793 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008794 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008795
8796 if (mLaunchingProviders.size() > 0) {
8797 if (needSep) pw.println(" ");
8798 pw.println(" Launching content providers:");
8799 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8800 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8801 pw.println(mLaunchingProviders.get(i));
8802 }
8803 needSep = true;
8804 }
8805
8806 if (mGrantedUriPermissions.size() > 0) {
8807 pw.println();
8808 pw.println("Granted Uri Permissions:");
8809 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8810 int uid = mGrantedUriPermissions.keyAt(i);
8811 HashMap<Uri, UriPermission> perms
8812 = mGrantedUriPermissions.valueAt(i);
8813 pw.print(" * UID "); pw.print(uid);
8814 pw.println(" holds:");
8815 for (UriPermission perm : perms.values()) {
8816 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008817 if (dumpAll) {
8818 perm.dump(pw, " ");
8819 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008820 }
8821 }
8822 needSep = true;
8823 }
8824
8825 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008826 }
8827
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008828 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8829 int opti, boolean dumpAll) {
8830 boolean needSep = false;
8831
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008832 if (this.mIntentSenderRecords.size() > 0) {
8833 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8834 Iterator<WeakReference<PendingIntentRecord>> it
8835 = mIntentSenderRecords.values().iterator();
8836 while (it.hasNext()) {
8837 WeakReference<PendingIntentRecord> ref = it.next();
8838 PendingIntentRecord rec = ref != null ? ref.get(): null;
8839 needSep = true;
8840 if (rec != null) {
8841 pw.print(" * "); pw.println(rec);
8842 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008843 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008844 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008845 } else {
8846 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008847 }
8848 }
8849 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008850
8851 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008852 }
8853
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008854 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8855 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008856 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008857 boolean needNL = false;
8858 final String innerPrefix = prefix + " ";
8859 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008860 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008861 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008862 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008863 if (needNL) {
8864 pw.println(" ");
8865 needNL = false;
8866 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008867 if (lastTask != r.task) {
8868 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008869 pw.print(prefix);
8870 pw.print(full ? "* " : " ");
8871 pw.println(lastTask);
8872 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008873 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008874 } else if (complete) {
8875 // Complete + brief == give a summary. Isn't that obvious?!?
8876 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008877 pw.print(prefix); pw.print(" ");
8878 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008879 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008881 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008882 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8883 pw.print(" #"); pw.print(i); pw.print(": ");
8884 pw.println(r);
8885 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008886 r.dump(pw, innerPrefix);
8887 } else if (complete) {
8888 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008889 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008890 if (r.app != null) {
8891 pw.print(innerPrefix); pw.println(r.app);
8892 }
8893 }
8894 if (client && r.app != null && r.app.thread != null) {
8895 // flush anything that is already in the PrintWriter since the thread is going
8896 // to write to the file descriptor directly
8897 pw.flush();
8898 try {
8899 TransferPipe tp = new TransferPipe();
8900 try {
8901 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8902 innerPrefix, args);
8903 // Short timeout, since blocking here can
8904 // deadlock with the application.
8905 tp.go(fd, 2000);
8906 } finally {
8907 tp.kill();
8908 }
8909 } catch (IOException e) {
8910 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8911 } catch (RemoteException e) {
8912 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8913 }
8914 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008915 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008916 }
8917 }
8918
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008919 private static String buildOomTag(String prefix, String space, int val, int base) {
8920 if (val == base) {
8921 if (space == null) return prefix;
8922 return prefix + " ";
8923 }
8924 return prefix + "+" + Integer.toString(val-base);
8925 }
8926
8927 private static final int dumpProcessList(PrintWriter pw,
8928 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008929 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008930 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008931 final int N = list.size()-1;
8932 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008933 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008934 pw.println(String.format("%s%s #%2d: %s",
8935 prefix, (r.persistent ? persistentLabel : normalLabel),
8936 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008937 if (r.persistent) {
8938 numPers++;
8939 }
8940 }
8941 return numPers;
8942 }
8943
Dianne Hackborn287952c2010-09-22 22:34:31 -07008944 private static final void dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07008945 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008946 String prefix, String normalLabel, String persistentLabel,
8947 boolean inclDetails) {
8948
Dianne Hackborn905577f2011-09-07 18:31:28 -07008949 ArrayList<Pair<ProcessRecord, Integer>> list
8950 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
8951 for (int i=0; i<origList.size(); i++) {
8952 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
8953 }
8954
8955 Comparator<Pair<ProcessRecord, Integer>> comparator
8956 = new Comparator<Pair<ProcessRecord, Integer>>() {
8957 @Override
8958 public int compare(Pair<ProcessRecord, Integer> object1,
8959 Pair<ProcessRecord, Integer> object2) {
8960 if (object1.first.setAdj != object2.first.setAdj) {
8961 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
8962 }
8963 if (object1.second.intValue() != object2.second.intValue()) {
8964 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
8965 }
8966 return 0;
8967 }
8968 };
8969
8970 Collections.sort(list, comparator);
8971
Dianne Hackborn287952c2010-09-22 22:34:31 -07008972 final long curRealtime = SystemClock.elapsedRealtime();
8973 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8974 final long curUptime = SystemClock.uptimeMillis();
8975 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8976
8977 final int N = list.size()-1;
8978 for (int i=N; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008979 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008980 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008981 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8982 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8983 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8984 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
8985 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
8986 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
8987 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
8988 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
8989 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
8990 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
8991 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8992 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
8993 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8994 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
8995 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
8996 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
8997 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
8998 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
8999 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
9000 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
9001 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9002 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009003 } else {
9004 oomAdj = Integer.toString(r.setAdj);
9005 }
9006 String schedGroup;
9007 switch (r.setSchedGroup) {
9008 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9009 schedGroup = "B";
9010 break;
9011 case Process.THREAD_GROUP_DEFAULT:
9012 schedGroup = "F";
9013 break;
9014 default:
9015 schedGroup = Integer.toString(r.setSchedGroup);
9016 break;
9017 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009018 String foreground;
9019 if (r.foregroundActivities) {
9020 foreground = "A";
9021 } else if (r.foregroundServices) {
9022 foreground = "S";
9023 } else {
9024 foreground = " ";
9025 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009026 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009027 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackborn905577f2011-09-07 18:31:28 -07009028 N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009029 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009030 if (r.adjSource != null || r.adjTarget != null) {
9031 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009032 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009033 if (r.adjTarget instanceof ComponentName) {
9034 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9035 } else if (r.adjTarget != null) {
9036 pw.print(r.adjTarget.toString());
9037 } else {
9038 pw.print("{null}");
9039 }
9040 pw.print("<=");
9041 if (r.adjSource instanceof ProcessRecord) {
9042 pw.print("Proc{");
9043 pw.print(((ProcessRecord)r.adjSource).toShortString());
9044 pw.println("}");
9045 } else if (r.adjSource != null) {
9046 pw.println(r.adjSource.toString());
9047 } else {
9048 pw.println("{null}");
9049 }
9050 }
9051 if (inclDetails) {
9052 pw.print(prefix);
9053 pw.print(" ");
9054 pw.print("oom: max="); pw.print(r.maxAdj);
9055 pw.print(" hidden="); pw.print(r.hiddenAdj);
9056 pw.print(" curRaw="); pw.print(r.curRawAdj);
9057 pw.print(" setRaw="); pw.print(r.setRawAdj);
9058 pw.print(" cur="); pw.print(r.curAdj);
9059 pw.print(" set="); pw.println(r.setAdj);
9060 pw.print(prefix);
9061 pw.print(" ");
9062 pw.print("keeping="); pw.print(r.keeping);
9063 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009064 pw.print(" empty="); pw.print(r.empty);
9065 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009066
9067 if (!r.keeping) {
9068 if (r.lastWakeTime != 0) {
9069 long wtime;
9070 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9071 synchronized (stats) {
9072 wtime = stats.getProcessWakeTime(r.info.uid,
9073 r.pid, curRealtime);
9074 }
9075 long timeUsed = wtime - r.lastWakeTime;
9076 pw.print(prefix);
9077 pw.print(" ");
9078 pw.print("keep awake over ");
9079 TimeUtils.formatDuration(realtimeSince, pw);
9080 pw.print(" used ");
9081 TimeUtils.formatDuration(timeUsed, pw);
9082 pw.print(" (");
9083 pw.print((timeUsed*100)/realtimeSince);
9084 pw.println("%)");
9085 }
9086 if (r.lastCpuTime != 0) {
9087 long timeUsed = r.curCpuTime - r.lastCpuTime;
9088 pw.print(prefix);
9089 pw.print(" ");
9090 pw.print("run cpu over ");
9091 TimeUtils.formatDuration(uptimeSince, pw);
9092 pw.print(" used ");
9093 TimeUtils.formatDuration(timeUsed, pw);
9094 pw.print(" (");
9095 pw.print((timeUsed*100)/uptimeSince);
9096 pw.println("%)");
9097 }
9098 }
9099 }
9100 }
9101 }
9102
Dianne Hackbornb437e092011-08-05 17:50:29 -07009103 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009104 ArrayList<ProcessRecord> procs;
9105 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009106 if (args != null && args.length > start
9107 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009108 procs = new ArrayList<ProcessRecord>();
9109 int pid = -1;
9110 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009111 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009112 } catch (NumberFormatException e) {
9113
9114 }
9115 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9116 ProcessRecord proc = mLruProcesses.get(i);
9117 if (proc.pid == pid) {
9118 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009119 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009120 procs.add(proc);
9121 }
9122 }
9123 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009124 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009125 return null;
9126 }
9127 } else {
9128 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9129 }
9130 }
9131 return procs;
9132 }
9133
9134 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9135 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009136 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009137 if (procs == null) {
9138 return;
9139 }
9140
9141 long uptime = SystemClock.uptimeMillis();
9142 long realtime = SystemClock.elapsedRealtime();
9143 pw.println("Applications Graphics Acceleration Info:");
9144 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9145
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009146 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9147 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009148 if (r.thread != null) {
9149 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9150 pw.flush();
9151 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009152 TransferPipe tp = new TransferPipe();
9153 try {
9154 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9155 tp.go(fd);
9156 } finally {
9157 tp.kill();
9158 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009159 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009160 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009161 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009162 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009163 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009164 pw.flush();
9165 }
9166 }
9167 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009168 }
9169
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009170 final static class MemItem {
9171 final String label;
9172 final long pss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009173 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009174
9175 public MemItem(String _label, long _pss) {
9176 label = _label;
9177 pss = _pss;
9178 }
9179 }
9180
Dianne Hackbornb437e092011-08-05 17:50:29 -07009181 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9182 boolean sort) {
9183 if (sort) {
9184 Collections.sort(items, new Comparator<MemItem>() {
9185 @Override
9186 public int compare(MemItem lhs, MemItem rhs) {
9187 if (lhs.pss < rhs.pss) {
9188 return 1;
9189 } else if (lhs.pss > rhs.pss) {
9190 return -1;
9191 }
9192 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009193 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009194 });
9195 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009196
9197 for (int i=0; i<items.size(); i++) {
9198 MemItem mi = items.get(i);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009199 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
9200 if (mi.subitems != null) {
9201 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9202 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009203 }
9204 }
9205
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009206 final void dumpApplicationMemoryUsage(FileDescriptor fd,
9207 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009208 boolean dumpAll = false;
9209
9210 int opti = 0;
9211 while (opti < args.length) {
9212 String opt = args[opti];
9213 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9214 break;
9215 }
9216 opti++;
9217 if ("-a".equals(opt)) {
9218 dumpAll = true;
9219 } else if ("-h".equals(opt)) {
9220 pw.println("meminfo dump options: [-a] [process]");
9221 pw.println(" -a: include all available information for each process.");
9222 pw.println("If [process] is specified it can be the name or ");
9223 pw.println("pid of a specific process to dump.");
9224 return;
9225 } else {
9226 pw.println("Unknown argument: " + opt + "; use -h for help");
9227 }
9228 }
9229
9230 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009231 if (procs == null) {
9232 return;
9233 }
9234
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009235 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009236 long uptime = SystemClock.uptimeMillis();
9237 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009238
9239 if (procs.size() == 1 || isCheckinRequest) {
9240 dumpAll = true;
9241 }
9242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009243 if (isCheckinRequest) {
9244 // short checkin version
9245 pw.println(uptime + "," + realtime);
9246 pw.flush();
9247 } else {
9248 pw.println("Applications Memory Usage (kB):");
9249 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9250 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009251
Dianne Hackbornb437e092011-08-05 17:50:29 -07009252 String[] innerArgs = new String[args.length-opti];
9253 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9254
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009255 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9256 long nativePss=0, dalvikPss=0, otherPss=0;
9257 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9258
Dianne Hackbornb437e092011-08-05 17:50:29 -07009259 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009260 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9261 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9262 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009263 };
9264 final String[] oomLabel = new String[] {
9265 "System", "Persistent", "Foreground",
9266 "Visible", "Perceptible", "Heavy Weight",
9267 "Backup", "Services", "Home", "Background"
9268 };
9269 long oomPss[] = new long[oomLabel.length];
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009270 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009271
9272 long totalPss = 0;
9273
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009274 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9275 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009276 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009277 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009278 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9279 pw.flush();
9280 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009281 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009282 if (dumpAll) {
9283 try {
9284 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9285 } catch (RemoteException e) {
9286 if (!isCheckinRequest) {
9287 pw.println("Got RemoteException!");
9288 pw.flush();
9289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009290 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009291 } else {
9292 mi = new Debug.MemoryInfo();
9293 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009294 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009295
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009296 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009297 long myTotalPss = mi.getTotalPss();
9298 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009299 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9300 myTotalPss);
9301 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009302
9303 nativePss += mi.nativePss;
9304 dalvikPss += mi.dalvikPss;
9305 otherPss += mi.otherPss;
9306 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9307 long mem = mi.getOtherPss(j);
9308 miscPss[j] += mem;
9309 otherPss -= mem;
9310 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009311
9312 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9313 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9314 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009315 if (oomProcs[oomIndex] == null) {
9316 oomProcs[oomIndex] = new ArrayList<MemItem>();
9317 }
9318 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009319 break;
9320 }
9321 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009323 }
9324 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009325
9326 if (!isCheckinRequest && procs.size() > 1) {
9327 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9328
9329 catMems.add(new MemItem("Native", nativePss));
9330 catMems.add(new MemItem("Dalvik", dalvikPss));
9331 catMems.add(new MemItem("Unknown", otherPss));
9332 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9333 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9334 }
9335
Dianne Hackbornb437e092011-08-05 17:50:29 -07009336 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9337 for (int j=0; j<oomPss.length; j++) {
9338 if (oomPss[j] != 0) {
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009339 MemItem item = new MemItem(oomLabel[j], oomPss[j]);
9340 item.subitems = oomProcs[j];
9341 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009342 }
9343 }
9344
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009345 pw.println();
9346 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009347 dumpMemItems(pw, " ", procMems, true);
9348 pw.println();
9349 pw.println("Total PSS by OOM adjustment:");
9350 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009351 pw.println();
9352 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009353 dumpMemItems(pw, " ", catMems, true);
9354 pw.println();
9355 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009357 }
9358
9359 /**
9360 * Searches array of arguments for the specified string
9361 * @param args array of argument strings
9362 * @param value value to search for
9363 * @return true if the value is contained in the array
9364 */
9365 private static boolean scanArgs(String[] args, String value) {
9366 if (args != null) {
9367 for (String arg : args) {
9368 if (value.equals(arg)) {
9369 return true;
9370 }
9371 }
9372 }
9373 return false;
9374 }
9375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009376 private final void killServicesLocked(ProcessRecord app,
9377 boolean allowRestart) {
9378 // Report disconnected services.
9379 if (false) {
9380 // XXX we are letting the client link to the service for
9381 // death notifications.
9382 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009383 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009384 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009385 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009386 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009387 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009388 = r.connections.values().iterator();
9389 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009390 ArrayList<ConnectionRecord> cl = jt.next();
9391 for (int i=0; i<cl.size(); i++) {
9392 ConnectionRecord c = cl.get(i);
9393 if (c.binding.client != app) {
9394 try {
9395 //c.conn.connected(r.className, null);
9396 } catch (Exception e) {
9397 // todo: this should be asynchronous!
9398 Slog.w(TAG, "Exception thrown disconnected servce "
9399 + r.shortName
9400 + " from app " + app.processName, e);
9401 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009402 }
9403 }
9404 }
9405 }
9406 }
9407 }
9408 }
9409
9410 // Clean up any connections this application has to other services.
9411 if (app.connections.size() > 0) {
9412 Iterator<ConnectionRecord> it = app.connections.iterator();
9413 while (it.hasNext()) {
9414 ConnectionRecord r = it.next();
9415 removeConnectionLocked(r, app, null);
9416 }
9417 }
9418 app.connections.clear();
9419
9420 if (app.services.size() != 0) {
9421 // Any services running in the application need to be placed
9422 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009423 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009424 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009425 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009426 synchronized (sr.stats.getBatteryStats()) {
9427 sr.stats.stopLaunchedLocked();
9428 }
9429 sr.app = null;
9430 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009431 if (mStoppingServices.remove(sr)) {
9432 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9433 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009434
9435 boolean hasClients = sr.bindings.size() > 0;
9436 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009437 Iterator<IntentBindRecord> bindings
9438 = sr.bindings.values().iterator();
9439 while (bindings.hasNext()) {
9440 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009441 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009442 + ": shouldUnbind=" + b.hasBound);
9443 b.binder = null;
9444 b.requested = b.received = b.hasBound = false;
9445 }
9446 }
9447
Dianne Hackborn070783f2010-12-29 16:46:28 -08009448 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9449 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009450 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009451 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009452 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009453 sr.crashCount, sr.shortName, app.pid);
9454 bringDownServiceLocked(sr, true);
9455 } else if (!allowRestart) {
9456 bringDownServiceLocked(sr, true);
9457 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009458 boolean canceled = scheduleServiceRestartLocked(sr, true);
9459
9460 // Should the service remain running? Note that in the
9461 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009462 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009463 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9464 if (sr.pendingStarts.size() == 0) {
9465 sr.startRequested = false;
9466 if (!hasClients) {
9467 // Whoops, no reason to restart!
9468 bringDownServiceLocked(sr, true);
9469 }
9470 }
9471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009472 }
9473 }
9474
9475 if (!allowRestart) {
9476 app.services.clear();
9477 }
9478 }
9479
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009480 // Make sure we have no more records on the stopping list.
9481 int i = mStoppingServices.size();
9482 while (i > 0) {
9483 i--;
9484 ServiceRecord sr = mStoppingServices.get(i);
9485 if (sr.app == app) {
9486 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009487 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009488 }
9489 }
9490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009491 app.executingServices.clear();
9492 }
9493
9494 private final void removeDyingProviderLocked(ProcessRecord proc,
9495 ContentProviderRecord cpr) {
9496 synchronized (cpr) {
9497 cpr.launchingApp = null;
9498 cpr.notifyAll();
9499 }
9500
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009501 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009502 String names[] = cpr.info.authority.split(";");
9503 for (int j = 0; j < names.length; j++) {
9504 mProvidersByName.remove(names[j]);
9505 }
9506
9507 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9508 while (cit.hasNext()) {
9509 ProcessRecord capp = cit.next();
9510 if (!capp.persistent && capp.thread != null
9511 && capp.pid != 0
9512 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009513 Slog.i(TAG, "Kill " + capp.processName
9514 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009515 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -07009516 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009517 capp.processName, capp.setAdj, "dying provider "
9518 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009519 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009520 }
9521 }
9522
9523 mLaunchingProviders.remove(cpr);
9524 }
9525
9526 /**
9527 * Main code for cleaning up a process when it has gone away. This is
9528 * called both as a result of the process dying, or directly when stopping
9529 * a process when running in single process mode.
9530 */
9531 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009532 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009533 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009534 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009535 }
9536
Dianne Hackborn36124872009-10-08 16:22:03 -07009537 mProcessesToGc.remove(app);
9538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009539 // Dismiss any open dialogs.
9540 if (app.crashDialog != null) {
9541 app.crashDialog.dismiss();
9542 app.crashDialog = null;
9543 }
9544 if (app.anrDialog != null) {
9545 app.anrDialog.dismiss();
9546 app.anrDialog = null;
9547 }
9548 if (app.waitDialog != null) {
9549 app.waitDialog.dismiss();
9550 app.waitDialog = null;
9551 }
9552
9553 app.crashing = false;
9554 app.notResponding = false;
9555
9556 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009557 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009558 app.thread = null;
9559 app.forcingToForeground = null;
9560 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009561 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009562 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009563 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009564
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009565 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009566
9567 boolean restart = false;
9568
9569 int NL = mLaunchingProviders.size();
9570
9571 // Remove published content providers.
9572 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009573 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009574 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009575 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009576 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009577 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009578
9579 // See if someone is waiting for this provider... in which
9580 // case we don't remove it, but just let it restart.
9581 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009582 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009583 for (; i<NL; i++) {
9584 if (mLaunchingProviders.get(i) == cpr) {
9585 restart = true;
9586 break;
9587 }
9588 }
9589 } else {
9590 i = NL;
9591 }
9592
9593 if (i >= NL) {
9594 removeDyingProviderLocked(app, cpr);
9595 NL = mLaunchingProviders.size();
9596 }
9597 }
9598 app.pubProviders.clear();
9599 }
9600
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009601 // Take care of any launching providers waiting for this process.
9602 if (checkAppInLaunchingProvidersLocked(app, false)) {
9603 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009604 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009606 // Unregister from connected content providers.
9607 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009608 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009609 while (it.hasNext()) {
9610 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9611 cpr.clients.remove(app);
9612 }
9613 app.conProviders.clear();
9614 }
9615
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009616 // At this point there may be remaining entries in mLaunchingProviders
9617 // where we were the only one waiting, so they are no longer of use.
9618 // Look for these and clean up if found.
9619 // XXX Commented out for now. Trying to figure out a way to reproduce
9620 // the actual situation to identify what is actually going on.
9621 if (false) {
9622 for (int i=0; i<NL; i++) {
9623 ContentProviderRecord cpr = (ContentProviderRecord)
9624 mLaunchingProviders.get(i);
9625 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9626 synchronized (cpr) {
9627 cpr.launchingApp = null;
9628 cpr.notifyAll();
9629 }
9630 }
9631 }
9632 }
9633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009634 skipCurrentReceiverLocked(app);
9635
9636 // Unregister any receivers.
9637 if (app.receivers.size() > 0) {
9638 Iterator<ReceiverList> it = app.receivers.iterator();
9639 while (it.hasNext()) {
9640 removeReceiverLocked(it.next());
9641 }
9642 app.receivers.clear();
9643 }
9644
Christopher Tate181fafa2009-05-14 11:12:14 -07009645 // If the app is undergoing backup, tell the backup manager about it
9646 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009647 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009648 try {
9649 IBackupManager bm = IBackupManager.Stub.asInterface(
9650 ServiceManager.getService(Context.BACKUP_SERVICE));
9651 bm.agentDisconnected(app.info.packageName);
9652 } catch (RemoteException e) {
9653 // can't happen; backup manager is local
9654 }
9655 }
9656
Jeff Sharkey287bd832011-05-28 19:36:26 -07009657 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009659 // If the caller is restarting this app, then leave it in its
9660 // current lists and let the caller take care of it.
9661 if (restarting) {
9662 return;
9663 }
9664
9665 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009666 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009667 "Removing non-persistent process during cleanup: " + app);
9668 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009669 if (mHeavyWeightProcess == app) {
9670 mHeavyWeightProcess = null;
9671 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9672 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009673 } else if (!app.removed) {
9674 // This app is persistent, so we need to keep its record around.
9675 // If it is not already on the pending app list, add it there
9676 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009677 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9678 mPersistentStartingProcesses.add(app);
9679 restart = true;
9680 }
9681 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009682 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9683 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009684 mProcessesOnHold.remove(app);
9685
The Android Open Source Project4df24232009-03-05 14:34:35 -08009686 if (app == mHomeProcess) {
9687 mHomeProcess = null;
9688 }
9689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009690 if (restart) {
9691 // We have components that still need to be running in the
9692 // process, so re-launch it.
9693 mProcessNames.put(app.processName, app.info.uid, app);
9694 startProcessLocked(app, "restart", app.processName);
9695 } else if (app.pid > 0 && app.pid != MY_PID) {
9696 // Goodbye!
9697 synchronized (mPidsSelfLocked) {
9698 mPidsSelfLocked.remove(app.pid);
9699 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9700 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009701 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009702 }
9703 }
9704
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009705 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9706 // Look through the content providers we are waiting to have launched,
9707 // and if any run in this process then either schedule a restart of
9708 // the process or kill the client waiting for it if this process has
9709 // gone bad.
9710 int NL = mLaunchingProviders.size();
9711 boolean restart = false;
9712 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009713 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009714 if (cpr.launchingApp == app) {
9715 if (!alwaysBad && !app.bad) {
9716 restart = true;
9717 } else {
9718 removeDyingProviderLocked(app, cpr);
9719 NL = mLaunchingProviders.size();
9720 }
9721 }
9722 }
9723 return restart;
9724 }
9725
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009726 // =========================================================
9727 // SERVICES
9728 // =========================================================
9729
9730 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9731 ActivityManager.RunningServiceInfo info =
9732 new ActivityManager.RunningServiceInfo();
9733 info.service = r.name;
9734 if (r.app != null) {
9735 info.pid = r.app.pid;
9736 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009737 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009738 info.process = r.processName;
9739 info.foreground = r.isForeground;
9740 info.activeSince = r.createTime;
9741 info.started = r.startRequested;
9742 info.clientCount = r.connections.size();
9743 info.crashCount = r.crashCount;
9744 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009745 if (r.isForeground) {
9746 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9747 }
9748 if (r.startRequested) {
9749 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9750 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009751 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009752 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9753 }
9754 if (r.app != null && r.app.persistent) {
9755 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9756 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009757
9758 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9759 for (int i=0; i<connl.size(); i++) {
9760 ConnectionRecord conn = connl.get(i);
9761 if (conn.clientLabel != 0) {
9762 info.clientPackage = conn.binding.client.info.packageName;
9763 info.clientLabel = conn.clientLabel;
9764 return info;
9765 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009766 }
9767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009768 return info;
9769 }
9770
9771 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9772 int flags) {
9773 synchronized (this) {
9774 ArrayList<ActivityManager.RunningServiceInfo> res
9775 = new ArrayList<ActivityManager.RunningServiceInfo>();
9776
9777 if (mServices.size() > 0) {
9778 Iterator<ServiceRecord> it = mServices.values().iterator();
9779 while (it.hasNext() && res.size() < maxNum) {
9780 res.add(makeRunningServiceInfoLocked(it.next()));
9781 }
9782 }
9783
9784 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9785 ServiceRecord r = mRestartingServices.get(i);
9786 ActivityManager.RunningServiceInfo info =
9787 makeRunningServiceInfoLocked(r);
9788 info.restarting = r.nextRestartTime;
9789 res.add(info);
9790 }
9791
9792 return res;
9793 }
9794 }
9795
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009796 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9797 synchronized (this) {
9798 ServiceRecord r = mServices.get(name);
9799 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009800 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9801 for (int i=0; i<conn.size(); i++) {
9802 if (conn.get(i).clientIntent != null) {
9803 return conn.get(i).clientIntent;
9804 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009805 }
9806 }
9807 }
9808 }
9809 return null;
9810 }
9811
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009812 private final ServiceRecord findServiceLocked(ComponentName name,
9813 IBinder token) {
9814 ServiceRecord r = mServices.get(name);
9815 return r == token ? r : null;
9816 }
9817
9818 private final class ServiceLookupResult {
9819 final ServiceRecord record;
9820 final String permission;
9821
9822 ServiceLookupResult(ServiceRecord _record, String _permission) {
9823 record = _record;
9824 permission = _permission;
9825 }
9826 };
9827
9828 private ServiceLookupResult findServiceLocked(Intent service,
9829 String resolvedType) {
9830 ServiceRecord r = null;
9831 if (service.getComponent() != null) {
9832 r = mServices.get(service.getComponent());
9833 }
9834 if (r == null) {
9835 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9836 r = mServicesByIntent.get(filter);
9837 }
9838
9839 if (r == null) {
9840 try {
9841 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009842 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009843 service, resolvedType, 0);
9844 ServiceInfo sInfo =
9845 rInfo != null ? rInfo.serviceInfo : null;
9846 if (sInfo == null) {
9847 return null;
9848 }
9849
9850 ComponentName name = new ComponentName(
9851 sInfo.applicationInfo.packageName, sInfo.name);
9852 r = mServices.get(name);
9853 } catch (RemoteException ex) {
9854 // pm is in same process, this will never happen.
9855 }
9856 }
9857 if (r != null) {
9858 int callingPid = Binder.getCallingPid();
9859 int callingUid = Binder.getCallingUid();
9860 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009861 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009862 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009863 if (!r.exported) {
9864 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9865 + " from pid=" + callingPid
9866 + ", uid=" + callingUid
9867 + " that is not exported from uid " + r.appInfo.uid);
9868 return new ServiceLookupResult(null, "not exported from uid "
9869 + r.appInfo.uid);
9870 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009871 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009872 + " from pid=" + callingPid
9873 + ", uid=" + callingUid
9874 + " requires " + r.permission);
9875 return new ServiceLookupResult(null, r.permission);
9876 }
9877 return new ServiceLookupResult(r, null);
9878 }
9879 return null;
9880 }
9881
9882 private class ServiceRestarter implements Runnable {
9883 private ServiceRecord mService;
9884
9885 void setService(ServiceRecord service) {
9886 mService = service;
9887 }
9888
9889 public void run() {
9890 synchronized(ActivityManagerService.this) {
9891 performServiceRestartLocked(mService);
9892 }
9893 }
9894 }
9895
9896 private ServiceLookupResult retrieveServiceLocked(Intent service,
9897 String resolvedType, int callingPid, int callingUid) {
9898 ServiceRecord r = null;
9899 if (service.getComponent() != null) {
9900 r = mServices.get(service.getComponent());
9901 }
9902 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9903 r = mServicesByIntent.get(filter);
9904 if (r == null) {
9905 try {
9906 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009907 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009908 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009909 ServiceInfo sInfo =
9910 rInfo != null ? rInfo.serviceInfo : null;
9911 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009912 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009913 ": not found");
9914 return null;
9915 }
9916
9917 ComponentName name = new ComponentName(
9918 sInfo.applicationInfo.packageName, sInfo.name);
9919 r = mServices.get(name);
9920 if (r == null) {
9921 filter = new Intent.FilterComparison(service.cloneFilter());
9922 ServiceRestarter res = new ServiceRestarter();
9923 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9924 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9925 synchronized (stats) {
9926 ss = stats.getServiceStatsLocked(
9927 sInfo.applicationInfo.uid, sInfo.packageName,
9928 sInfo.name);
9929 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009930 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009931 res.setService(r);
9932 mServices.put(name, r);
9933 mServicesByIntent.put(filter, r);
9934
9935 // Make sure this component isn't in the pending list.
9936 int N = mPendingServices.size();
9937 for (int i=0; i<N; i++) {
9938 ServiceRecord pr = mPendingServices.get(i);
9939 if (pr.name.equals(name)) {
9940 mPendingServices.remove(i);
9941 i--;
9942 N--;
9943 }
9944 }
9945 }
9946 } catch (RemoteException ex) {
9947 // pm is in same process, this will never happen.
9948 }
9949 }
9950 if (r != null) {
9951 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009952 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009953 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009954 if (!r.exported) {
9955 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9956 + " from pid=" + callingPid
9957 + ", uid=" + callingUid
9958 + " that is not exported from uid " + r.appInfo.uid);
9959 return new ServiceLookupResult(null, "not exported from uid "
9960 + r.appInfo.uid);
9961 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009962 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009963 + " from pid=" + callingPid
9964 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009965 + " requires " + r.permission);
9966 return new ServiceLookupResult(null, r.permission);
9967 }
9968 return new ServiceLookupResult(r, null);
9969 }
9970 return null;
9971 }
9972
Dianne Hackborn287952c2010-09-22 22:34:31 -07009973 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9974 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9975 + why + " of " + r + " in app " + r.app);
9976 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9977 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009978 long now = SystemClock.uptimeMillis();
9979 if (r.executeNesting == 0 && r.app != null) {
9980 if (r.app.executingServices.size() == 0) {
9981 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9982 msg.obj = r.app;
9983 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9984 }
9985 r.app.executingServices.add(r);
9986 }
9987 r.executeNesting++;
9988 r.executingStart = now;
9989 }
9990
9991 private final void sendServiceArgsLocked(ServiceRecord r,
9992 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009993 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009994 if (N == 0) {
9995 return;
9996 }
9997
Dianne Hackborn39792d22010-08-19 18:01:52 -07009998 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009999 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010000 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010001 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10002 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010003 if (si.intent == null && N > 1) {
10004 // If somehow we got a dummy null intent in the middle,
10005 // then skip it. DO NOT skip a null intent when it is
10006 // the only one in the list -- this is to support the
10007 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010008 continue;
10009 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010010 si.deliveredTime = SystemClock.uptimeMillis();
10011 r.deliveredStarts.add(si);
10012 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010013 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010014 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010015 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010016 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010017 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010018 if (!oomAdjusted) {
10019 oomAdjusted = true;
10020 updateOomAdjLocked(r.app);
10021 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010022 int flags = 0;
10023 if (si.deliveryCount > 0) {
10024 flags |= Service.START_FLAG_RETRY;
10025 }
10026 if (si.doneExecutingCount > 0) {
10027 flags |= Service.START_FLAG_REDELIVERY;
10028 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010029 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010030 } catch (RemoteException e) {
10031 // Remote process gone... we'll let the normal cleanup take
10032 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010033 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010034 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010035 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010036 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010037 break;
10038 }
10039 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010040 }
10041
10042 private final boolean requestServiceBindingLocked(ServiceRecord r,
10043 IntentBindRecord i, boolean rebind) {
10044 if (r.app == null || r.app.thread == null) {
10045 // If service is not currently running, can't yet bind.
10046 return false;
10047 }
10048 if ((!i.requested || rebind) && i.apps.size() > 0) {
10049 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010050 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010051 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10052 if (!rebind) {
10053 i.requested = true;
10054 }
10055 i.hasBound = true;
10056 i.doRebind = false;
10057 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010058 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010059 return false;
10060 }
10061 }
10062 return true;
10063 }
10064
10065 private final void requestServiceBindingsLocked(ServiceRecord r) {
10066 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10067 while (bindings.hasNext()) {
10068 IntentBindRecord i = bindings.next();
10069 if (!requestServiceBindingLocked(r, i, false)) {
10070 break;
10071 }
10072 }
10073 }
10074
10075 private final void realStartServiceLocked(ServiceRecord r,
10076 ProcessRecord app) throws RemoteException {
10077 if (app.thread == null) {
10078 throw new RemoteException();
10079 }
10080
10081 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010082 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010083
10084 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010085 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010086 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010087
10088 boolean created = false;
10089 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010090 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010091 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010092 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010093 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010094 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010095 synchronized (r.stats.getBatteryStats()) {
10096 r.stats.startLaunchedLocked();
10097 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010098 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010099 app.thread.scheduleCreateService(r, r.serviceInfo,
10100 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010101 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010102 created = true;
10103 } finally {
10104 if (!created) {
10105 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010106 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010107 }
10108 }
10109
10110 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010111
10112 // If the service is in the started state, and there are no
10113 // pending arguments, then fake up one so its onStartCommand() will
10114 // be called.
10115 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010116 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10117 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010118 }
10119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010120 sendServiceArgsLocked(r, true);
10121 }
10122
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010123 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10124 boolean allowCancel) {
10125 boolean canceled = false;
10126
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010127 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010128 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010129 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010130
Dianne Hackborn070783f2010-12-29 16:46:28 -080010131 if ((r.serviceInfo.applicationInfo.flags
10132 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10133 minDuration /= 4;
10134 }
10135
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010136 // Any delivered but not yet finished starts should be put back
10137 // on the pending list.
10138 final int N = r.deliveredStarts.size();
10139 if (N > 0) {
10140 for (int i=N-1; i>=0; i--) {
10141 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010142 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010143 if (si.intent == null) {
10144 // We'll generate this again if needed.
10145 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10146 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10147 r.pendingStarts.add(0, si);
10148 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10149 dur *= 2;
10150 if (minDuration < dur) minDuration = dur;
10151 if (resetTime < dur) resetTime = dur;
10152 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010153 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010154 + r.name);
10155 canceled = true;
10156 }
10157 }
10158 r.deliveredStarts.clear();
10159 }
10160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010161 r.totalRestartCount++;
10162 if (r.restartDelay == 0) {
10163 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010164 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010165 } else {
10166 // If it has been a "reasonably long time" since the service
10167 // was started, then reset our restart duration back to
10168 // the beginning, so we don't infinitely increase the duration
10169 // on a service that just occasionally gets killed (which is
10170 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010171 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010172 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010173 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010174 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010175 if ((r.serviceInfo.applicationInfo.flags
10176 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10177 // Services in peristent processes will restart much more
10178 // quickly, since they are pretty important. (Think SystemUI).
10179 r.restartDelay += minDuration/2;
10180 } else {
10181 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10182 if (r.restartDelay < minDuration) {
10183 r.restartDelay = minDuration;
10184 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010185 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010186 }
10187 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010188
10189 r.nextRestartTime = now + r.restartDelay;
10190
10191 // Make sure that we don't end up restarting a bunch of services
10192 // all at the same time.
10193 boolean repeat;
10194 do {
10195 repeat = false;
10196 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10197 ServiceRecord r2 = mRestartingServices.get(i);
10198 if (r2 != r && r.nextRestartTime
10199 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10200 && r.nextRestartTime
10201 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10202 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10203 r.restartDelay = r.nextRestartTime - now;
10204 repeat = true;
10205 break;
10206 }
10207 }
10208 } while (repeat);
10209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010210 if (!mRestartingServices.contains(r)) {
10211 mRestartingServices.add(r);
10212 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010213
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010214 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010216 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010217 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010218 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010219 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010220 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010221 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010222 r.shortName, r.restartDelay);
10223
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010224 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010225 }
10226
10227 final void performServiceRestartLocked(ServiceRecord r) {
10228 if (!mRestartingServices.contains(r)) {
10229 return;
10230 }
10231 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10232 }
10233
10234 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10235 if (r.restartDelay == 0) {
10236 return false;
10237 }
10238 r.resetRestartCounter();
10239 mRestartingServices.remove(r);
10240 mHandler.removeCallbacks(r.restarter);
10241 return true;
10242 }
10243
10244 private final boolean bringUpServiceLocked(ServiceRecord r,
10245 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010246 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010247 //r.dump(" ");
10248
Dianne Hackborn36124872009-10-08 16:22:03 -070010249 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010250 sendServiceArgsLocked(r, false);
10251 return true;
10252 }
10253
10254 if (!whileRestarting && r.restartDelay > 0) {
10255 // If waiting for a restart, then do nothing.
10256 return true;
10257 }
10258
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010259 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010260
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010261 // We are now bringing the service up, so no longer in the
10262 // restarting state.
10263 mRestartingServices.remove(r);
10264
Dianne Hackborne7f97212011-02-24 14:40:20 -080010265 // Service is now being launched, its package can't be stopped.
10266 try {
10267 AppGlobals.getPackageManager().setPackageStoppedState(
10268 r.packageName, false);
10269 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010270 } catch (IllegalArgumentException e) {
10271 Slog.w(TAG, "Failed trying to unstop package "
10272 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010273 }
10274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010275 final String appName = r.processName;
10276 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10277 if (app != null && app.thread != null) {
10278 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010279 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010280 realStartServiceLocked(r, app);
10281 return true;
10282 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010283 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010284 }
10285
10286 // If a dead object exception was thrown -- fall through to
10287 // restart the application.
10288 }
10289
Dianne Hackborn36124872009-10-08 16:22:03 -070010290 // Not running -- get it started, and enqueue this service record
10291 // to be executed when the app comes up.
10292 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10293 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010294 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010295 + r.appInfo.packageName + "/"
10296 + r.appInfo.uid + " for service "
10297 + r.intent.getIntent() + ": process is bad");
10298 bringDownServiceLocked(r, true);
10299 return false;
10300 }
10301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010302 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010303 mPendingServices.add(r);
10304 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010306 return true;
10307 }
10308
10309 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010310 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010311 //r.dump(" ");
10312
10313 // Does it still need to run?
10314 if (!force && r.startRequested) {
10315 return;
10316 }
10317 if (r.connections.size() > 0) {
10318 if (!force) {
10319 // XXX should probably keep a count of the number of auto-create
10320 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010321 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010322 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010323 ArrayList<ConnectionRecord> cr = it.next();
10324 for (int i=0; i<cr.size(); i++) {
10325 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10326 return;
10327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010328 }
10329 }
10330 }
10331
10332 // Report to all of the connections that the service is no longer
10333 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010334 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010335 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010336 ArrayList<ConnectionRecord> c = it.next();
10337 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010338 ConnectionRecord cr = c.get(i);
10339 // There is still a connection to the service that is
10340 // being brought down. Mark it as dead.
10341 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010342 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010343 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010344 } catch (Exception e) {
10345 Slog.w(TAG, "Failure disconnecting service " + r.name +
10346 " to connection " + c.get(i).conn.asBinder() +
10347 " (in " + c.get(i).binding.client.processName + ")", e);
10348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010349 }
10350 }
10351 }
10352
10353 // Tell the service that it has been unbound.
10354 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10355 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10356 while (it.hasNext()) {
10357 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010358 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010359 + ": hasBound=" + ibr.hasBound);
10360 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10361 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010362 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010363 updateOomAdjLocked(r.app);
10364 ibr.hasBound = false;
10365 r.app.thread.scheduleUnbindService(r,
10366 ibr.intent.getIntent());
10367 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010368 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010369 + r.shortName, e);
10370 serviceDoneExecutingLocked(r, true);
10371 }
10372 }
10373 }
10374 }
10375
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010376 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010377 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010378 System.identityHashCode(r), r.shortName,
10379 (r.app != null) ? r.app.pid : -1);
10380
10381 mServices.remove(r.name);
10382 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010383 r.totalRestartCount = 0;
10384 unscheduleServiceRestartLocked(r);
10385
10386 // Also make sure it is not on the pending list.
10387 int N = mPendingServices.size();
10388 for (int i=0; i<N; i++) {
10389 if (mPendingServices.get(i) == r) {
10390 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010391 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010392 i--;
10393 N--;
10394 }
10395 }
10396
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010397 r.cancelNotification();
10398 r.isForeground = false;
10399 r.foregroundId = 0;
10400 r.foregroundNoti = null;
10401
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010402 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010403 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010404 r.pendingStarts.clear();
10405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010406 if (r.app != null) {
10407 synchronized (r.stats.getBatteryStats()) {
10408 r.stats.stopLaunchedLocked();
10409 }
10410 r.app.services.remove(r);
10411 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010412 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010413 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010414 mStoppingServices.add(r);
10415 updateOomAdjLocked(r.app);
10416 r.app.thread.scheduleStopService(r);
10417 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010418 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010419 + r.shortName, e);
10420 serviceDoneExecutingLocked(r, true);
10421 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010422 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010423 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010424 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010425 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010426 }
10427 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010428 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010429 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010430 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010431
10432 if (r.bindings.size() > 0) {
10433 r.bindings.clear();
10434 }
10435
10436 if (r.restarter instanceof ServiceRestarter) {
10437 ((ServiceRestarter)r.restarter).setService(null);
10438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010439 }
10440
10441 ComponentName startServiceLocked(IApplicationThread caller,
10442 Intent service, String resolvedType,
10443 int callingPid, int callingUid) {
10444 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010445 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010446 + " type=" + resolvedType + " args=" + service.getExtras());
10447
10448 if (caller != null) {
10449 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10450 if (callerApp == null) {
10451 throw new SecurityException(
10452 "Unable to find app for caller " + caller
10453 + " (pid=" + Binder.getCallingPid()
10454 + ") when starting service " + service);
10455 }
10456 }
10457
10458 ServiceLookupResult res =
10459 retrieveServiceLocked(service, resolvedType,
10460 callingPid, callingUid);
10461 if (res == null) {
10462 return null;
10463 }
10464 if (res.record == null) {
10465 return new ComponentName("!", res.permission != null
10466 ? res.permission : "private to package");
10467 }
10468 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010469 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10470 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010471 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010472 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010473 }
10474 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010475 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010476 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010477 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010478 r.lastActivity = SystemClock.uptimeMillis();
10479 synchronized (r.stats.getBatteryStats()) {
10480 r.stats.startRunningLocked();
10481 }
10482 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10483 return new ComponentName("!", "Service process is bad");
10484 }
10485 return r.name;
10486 }
10487 }
10488
10489 public ComponentName startService(IApplicationThread caller, Intent service,
10490 String resolvedType) {
10491 // Refuse possible leaked file descriptors
10492 if (service != null && service.hasFileDescriptors() == true) {
10493 throw new IllegalArgumentException("File descriptors passed in Intent");
10494 }
10495
10496 synchronized(this) {
10497 final int callingPid = Binder.getCallingPid();
10498 final int callingUid = Binder.getCallingUid();
10499 final long origId = Binder.clearCallingIdentity();
10500 ComponentName res = startServiceLocked(caller, service,
10501 resolvedType, callingPid, callingUid);
10502 Binder.restoreCallingIdentity(origId);
10503 return res;
10504 }
10505 }
10506
10507 ComponentName startServiceInPackage(int uid,
10508 Intent service, String resolvedType) {
10509 synchronized(this) {
10510 final long origId = Binder.clearCallingIdentity();
10511 ComponentName res = startServiceLocked(null, service,
10512 resolvedType, -1, uid);
10513 Binder.restoreCallingIdentity(origId);
10514 return res;
10515 }
10516 }
10517
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010518 private void stopServiceLocked(ServiceRecord service) {
10519 synchronized (service.stats.getBatteryStats()) {
10520 service.stats.stopRunningLocked();
10521 }
10522 service.startRequested = false;
10523 service.callStart = false;
10524 bringDownServiceLocked(service, false);
10525 }
10526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010527 public int stopService(IApplicationThread caller, Intent service,
10528 String resolvedType) {
10529 // Refuse possible leaked file descriptors
10530 if (service != null && service.hasFileDescriptors() == true) {
10531 throw new IllegalArgumentException("File descriptors passed in Intent");
10532 }
10533
10534 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010535 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010536 + " type=" + resolvedType);
10537
10538 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10539 if (caller != null && callerApp == null) {
10540 throw new SecurityException(
10541 "Unable to find app for caller " + caller
10542 + " (pid=" + Binder.getCallingPid()
10543 + ") when stopping service " + service);
10544 }
10545
10546 // If this service is active, make sure it is stopped.
10547 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10548 if (r != null) {
10549 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010550 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010551 try {
10552 stopServiceLocked(r.record);
10553 } finally {
10554 Binder.restoreCallingIdentity(origId);
10555 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010556 return 1;
10557 }
10558 return -1;
10559 }
10560 }
10561
10562 return 0;
10563 }
10564
10565 public IBinder peekService(Intent service, String resolvedType) {
10566 // Refuse possible leaked file descriptors
10567 if (service != null && service.hasFileDescriptors() == true) {
10568 throw new IllegalArgumentException("File descriptors passed in Intent");
10569 }
10570
10571 IBinder ret = null;
10572
10573 synchronized(this) {
10574 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10575
10576 if (r != null) {
10577 // r.record is null if findServiceLocked() failed the caller permission check
10578 if (r.record == null) {
10579 throw new SecurityException(
10580 "Permission Denial: Accessing service " + r.record.name
10581 + " from pid=" + Binder.getCallingPid()
10582 + ", uid=" + Binder.getCallingUid()
10583 + " requires " + r.permission);
10584 }
10585 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10586 if (ib != null) {
10587 ret = ib.binder;
10588 }
10589 }
10590 }
10591
10592 return ret;
10593 }
10594
10595 public boolean stopServiceToken(ComponentName className, IBinder token,
10596 int startId) {
10597 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010598 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010599 + " " + token + " startId=" + startId);
10600 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010601 if (r != null) {
10602 if (startId >= 0) {
10603 // Asked to only stop if done with all work. Note that
10604 // to avoid leaks, we will take this as dropping all
10605 // start items up to and including this one.
10606 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10607 if (si != null) {
10608 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010609 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10610 cur.removeUriPermissionsLocked();
10611 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010612 break;
10613 }
10614 }
10615 }
10616
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010617 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010618 return false;
10619 }
10620
10621 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010622 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010623 + " is last, but have " + r.deliveredStarts.size()
10624 + " remaining args");
10625 }
10626 }
10627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010628 synchronized (r.stats.getBatteryStats()) {
10629 r.stats.stopRunningLocked();
10630 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010631 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010632 }
10633 final long origId = Binder.clearCallingIdentity();
10634 bringDownServiceLocked(r, false);
10635 Binder.restoreCallingIdentity(origId);
10636 return true;
10637 }
10638 }
10639 return false;
10640 }
10641
10642 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010643 int id, Notification notification, boolean removeNotification) {
10644 final long origId = Binder.clearCallingIdentity();
10645 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010646 synchronized(this) {
10647 ServiceRecord r = findServiceLocked(className, token);
10648 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010649 if (id != 0) {
10650 if (notification == null) {
10651 throw new IllegalArgumentException("null notification");
10652 }
10653 if (r.foregroundId != id) {
10654 r.cancelNotification();
10655 r.foregroundId = id;
10656 }
10657 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10658 r.foregroundNoti = notification;
10659 r.isForeground = true;
10660 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010661 if (r.app != null) {
10662 updateServiceForegroundLocked(r.app, true);
10663 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010664 } else {
10665 if (r.isForeground) {
10666 r.isForeground = false;
10667 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010668 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010669 updateServiceForegroundLocked(r.app, true);
10670 }
10671 }
10672 if (removeNotification) {
10673 r.cancelNotification();
10674 r.foregroundId = 0;
10675 r.foregroundNoti = null;
10676 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010677 }
10678 }
10679 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010680 } finally {
10681 Binder.restoreCallingIdentity(origId);
10682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010683 }
10684
10685 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10686 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010687 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010688 if (sr.isForeground) {
10689 anyForeground = true;
10690 break;
10691 }
10692 }
10693 if (anyForeground != proc.foregroundServices) {
10694 proc.foregroundServices = anyForeground;
10695 if (oomAdj) {
10696 updateOomAdjLocked();
10697 }
10698 }
10699 }
10700
10701 public int bindService(IApplicationThread caller, IBinder token,
10702 Intent service, String resolvedType,
10703 IServiceConnection connection, int flags) {
10704 // Refuse possible leaked file descriptors
10705 if (service != null && service.hasFileDescriptors() == true) {
10706 throw new IllegalArgumentException("File descriptors passed in Intent");
10707 }
10708
10709 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010710 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010711 + " type=" + resolvedType + " conn=" + connection.asBinder()
10712 + " flags=0x" + Integer.toHexString(flags));
10713 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10714 if (callerApp == null) {
10715 throw new SecurityException(
10716 "Unable to find app for caller " + caller
10717 + " (pid=" + Binder.getCallingPid()
10718 + ") when binding service " + service);
10719 }
10720
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010721 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010722 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010723 activity = mMainStack.isInStackLocked(token);
10724 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010725 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010726 return 0;
10727 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010728 }
10729
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010730 int clientLabel = 0;
10731 PendingIntent clientIntent = null;
10732
10733 if (callerApp.info.uid == Process.SYSTEM_UID) {
10734 // Hacky kind of thing -- allow system stuff to tell us
10735 // what they are, so we can report this elsewhere for
10736 // others to know why certain services are running.
10737 try {
10738 clientIntent = (PendingIntent)service.getParcelableExtra(
10739 Intent.EXTRA_CLIENT_INTENT);
10740 } catch (RuntimeException e) {
10741 }
10742 if (clientIntent != null) {
10743 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10744 if (clientLabel != 0) {
10745 // There are no useful extras in the intent, trash them.
10746 // System code calling with this stuff just needs to know
10747 // this will happen.
10748 service = service.cloneFilter();
10749 }
10750 }
10751 }
10752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010753 ServiceLookupResult res =
10754 retrieveServiceLocked(service, resolvedType,
10755 Binder.getCallingPid(), Binder.getCallingUid());
10756 if (res == null) {
10757 return 0;
10758 }
10759 if (res.record == null) {
10760 return -1;
10761 }
10762 ServiceRecord s = res.record;
10763
10764 final long origId = Binder.clearCallingIdentity();
10765
10766 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010767 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010768 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010769 }
10770
10771 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10772 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010773 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010774
10775 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010776 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10777 if (clist == null) {
10778 clist = new ArrayList<ConnectionRecord>();
10779 s.connections.put(binder, clist);
10780 }
10781 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010782 b.connections.add(c);
10783 if (activity != null) {
10784 if (activity.connections == null) {
10785 activity.connections = new HashSet<ConnectionRecord>();
10786 }
10787 activity.connections.add(c);
10788 }
10789 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010790 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10791 b.client.hasAboveClient = true;
10792 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010793 clist = mServiceConnections.get(binder);
10794 if (clist == null) {
10795 clist = new ArrayList<ConnectionRecord>();
10796 mServiceConnections.put(binder, clist);
10797 }
10798 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010799
10800 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10801 s.lastActivity = SystemClock.uptimeMillis();
10802 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10803 return 0;
10804 }
10805 }
10806
10807 if (s.app != null) {
10808 // This could have made the service more important.
10809 updateOomAdjLocked(s.app);
10810 }
10811
Joe Onorato8a9b2202010-02-26 18:56:32 -080010812 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010813 + ": received=" + b.intent.received
10814 + " apps=" + b.intent.apps.size()
10815 + " doRebind=" + b.intent.doRebind);
10816
10817 if (s.app != null && b.intent.received) {
10818 // Service is already running, so we can immediately
10819 // publish the connection.
10820 try {
10821 c.conn.connected(s.name, b.intent.binder);
10822 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010823 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010824 + " to connection " + c.conn.asBinder()
10825 + " (in " + c.binding.client.processName + ")", e);
10826 }
10827
10828 // If this is the first app connected back to this binding,
10829 // and the service had previously asked to be told when
10830 // rebound, then do so.
10831 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10832 requestServiceBindingLocked(s, b.intent, true);
10833 }
10834 } else if (!b.intent.requested) {
10835 requestServiceBindingLocked(s, b.intent, false);
10836 }
10837
10838 Binder.restoreCallingIdentity(origId);
10839 }
10840
10841 return 1;
10842 }
10843
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010844 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010845 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010846 IBinder binder = c.conn.asBinder();
10847 AppBindRecord b = c.binding;
10848 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010849 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10850 if (clist != null) {
10851 clist.remove(c);
10852 if (clist.size() == 0) {
10853 s.connections.remove(binder);
10854 }
10855 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010856 b.connections.remove(c);
10857 if (c.activity != null && c.activity != skipAct) {
10858 if (c.activity.connections != null) {
10859 c.activity.connections.remove(c);
10860 }
10861 }
10862 if (b.client != skipApp) {
10863 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010864 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10865 b.client.updateHasAboveClientLocked();
10866 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010867 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010868 clist = mServiceConnections.get(binder);
10869 if (clist != null) {
10870 clist.remove(c);
10871 if (clist.size() == 0) {
10872 mServiceConnections.remove(binder);
10873 }
10874 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010875
10876 if (b.connections.size() == 0) {
10877 b.intent.apps.remove(b.client);
10878 }
10879
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010880 if (!c.serviceDead) {
10881 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10882 + ": shouldUnbind=" + b.intent.hasBound);
10883 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10884 && b.intent.hasBound) {
10885 try {
10886 bumpServiceExecutingLocked(s, "unbind");
10887 updateOomAdjLocked(s.app);
10888 b.intent.hasBound = false;
10889 // Assume the client doesn't want to know about a rebind;
10890 // we will deal with that later if it asks for one.
10891 b.intent.doRebind = false;
10892 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10893 } catch (Exception e) {
10894 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10895 serviceDoneExecutingLocked(s, true);
10896 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010897 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010898
10899 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10900 bringDownServiceLocked(s, false);
10901 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010902 }
10903 }
10904
10905 public boolean unbindService(IServiceConnection connection) {
10906 synchronized (this) {
10907 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010908 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010909 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10910 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010911 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010912 + connection.asBinder());
10913 return false;
10914 }
10915
10916 final long origId = Binder.clearCallingIdentity();
10917
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010918 while (clist.size() > 0) {
10919 ConnectionRecord r = clist.get(0);
10920 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010921
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010922 if (r.binding.service.app != null) {
10923 // This could have made the service less important.
10924 updateOomAdjLocked(r.binding.service.app);
10925 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010926 }
10927
10928 Binder.restoreCallingIdentity(origId);
10929 }
10930
10931 return true;
10932 }
10933
10934 public void publishService(IBinder token, Intent intent, IBinder service) {
10935 // Refuse possible leaked file descriptors
10936 if (intent != null && intent.hasFileDescriptors() == true) {
10937 throw new IllegalArgumentException("File descriptors passed in Intent");
10938 }
10939
10940 synchronized(this) {
10941 if (!(token instanceof ServiceRecord)) {
10942 throw new IllegalArgumentException("Invalid service token");
10943 }
10944 ServiceRecord r = (ServiceRecord)token;
10945
10946 final long origId = Binder.clearCallingIdentity();
10947
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010948 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010949 + " " + intent + ": " + service);
10950 if (r != null) {
10951 Intent.FilterComparison filter
10952 = new Intent.FilterComparison(intent);
10953 IntentBindRecord b = r.bindings.get(filter);
10954 if (b != null && !b.received) {
10955 b.binder = service;
10956 b.requested = true;
10957 b.received = true;
10958 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010959 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010960 = r.connections.values().iterator();
10961 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010962 ArrayList<ConnectionRecord> clist = it.next();
10963 for (int i=0; i<clist.size(); i++) {
10964 ConnectionRecord c = clist.get(i);
10965 if (!filter.equals(c.binding.intent.intent)) {
10966 if (DEBUG_SERVICE) Slog.v(
10967 TAG, "Not publishing to: " + c);
10968 if (DEBUG_SERVICE) Slog.v(
10969 TAG, "Bound intent: " + c.binding.intent.intent);
10970 if (DEBUG_SERVICE) Slog.v(
10971 TAG, "Published intent: " + intent);
10972 continue;
10973 }
10974 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10975 try {
10976 c.conn.connected(r.name, service);
10977 } catch (Exception e) {
10978 Slog.w(TAG, "Failure sending service " + r.name +
10979 " to connection " + c.conn.asBinder() +
10980 " (in " + c.binding.client.processName + ")", e);
10981 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010982 }
10983 }
10984 }
10985 }
10986
10987 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10988
10989 Binder.restoreCallingIdentity(origId);
10990 }
10991 }
10992 }
10993
10994 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10995 // Refuse possible leaked file descriptors
10996 if (intent != null && intent.hasFileDescriptors() == true) {
10997 throw new IllegalArgumentException("File descriptors passed in Intent");
10998 }
10999
11000 synchronized(this) {
11001 if (!(token instanceof ServiceRecord)) {
11002 throw new IllegalArgumentException("Invalid service token");
11003 }
11004 ServiceRecord r = (ServiceRecord)token;
11005
11006 final long origId = Binder.clearCallingIdentity();
11007
11008 if (r != null) {
11009 Intent.FilterComparison filter
11010 = new Intent.FilterComparison(intent);
11011 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011012 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011013 + " at " + b + ": apps="
11014 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011015
11016 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011017 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011018 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011019 // Applications have already bound since the last
11020 // unbind, so just rebind right here.
11021 requestServiceBindingLocked(r, b, true);
11022 } else {
11023 // Note to tell the service the next time there is
11024 // a new client.
11025 b.doRebind = true;
11026 }
11027 }
11028
Per Edelberg78f9fff2010-08-30 20:01:35 +020011029 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011030
11031 Binder.restoreCallingIdentity(origId);
11032 }
11033 }
11034 }
11035
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011036 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011037 synchronized(this) {
11038 if (!(token instanceof ServiceRecord)) {
11039 throw new IllegalArgumentException("Invalid service token");
11040 }
11041 ServiceRecord r = (ServiceRecord)token;
11042 boolean inStopping = mStoppingServices.contains(token);
11043 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011044 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011045 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011046 + " with incorrect token: given " + token
11047 + ", expected " + r);
11048 return;
11049 }
11050
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011051 if (type == 1) {
11052 // This is a call from a service start... take care of
11053 // book-keeping.
11054 r.callStart = true;
11055 switch (res) {
11056 case Service.START_STICKY_COMPATIBILITY:
11057 case Service.START_STICKY: {
11058 // We are done with the associated start arguments.
11059 r.findDeliveredStart(startId, true);
11060 // Don't stop if killed.
11061 r.stopIfKilled = false;
11062 break;
11063 }
11064 case Service.START_NOT_STICKY: {
11065 // We are done with the associated start arguments.
11066 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011067 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011068 // There is no more work, and this service
11069 // doesn't want to hang around if killed.
11070 r.stopIfKilled = true;
11071 }
11072 break;
11073 }
11074 case Service.START_REDELIVER_INTENT: {
11075 // We'll keep this item until they explicitly
11076 // call stop for it, but keep track of the fact
11077 // that it was delivered.
11078 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11079 if (si != null) {
11080 si.deliveryCount = 0;
11081 si.doneExecutingCount++;
11082 // Don't stop if killed.
11083 r.stopIfKilled = true;
11084 }
11085 break;
11086 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011087 case Service.START_TASK_REMOVED_COMPLETE: {
11088 // Special processing for onTaskRemoved(). Don't
11089 // impact normal onStartCommand() processing.
11090 r.findDeliveredStart(startId, true);
11091 break;
11092 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011093 default:
11094 throw new IllegalArgumentException(
11095 "Unknown service start result: " + res);
11096 }
11097 if (res == Service.START_STICKY_COMPATIBILITY) {
11098 r.callStart = false;
11099 }
11100 }
11101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011102 final long origId = Binder.clearCallingIdentity();
11103 serviceDoneExecutingLocked(r, inStopping);
11104 Binder.restoreCallingIdentity(origId);
11105 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011106 Slog.w(TAG, "Done executing unknown service from pid "
11107 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011108 }
11109 }
11110 }
11111
11112 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011113 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11114 + ": nesting=" + r.executeNesting
11115 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011116 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011117 r.executeNesting--;
11118 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011119 if (DEBUG_SERVICE) Slog.v(TAG,
11120 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011121 r.app.executingServices.remove(r);
11122 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011123 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11124 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011125 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11126 }
11127 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011128 if (DEBUG_SERVICE) Slog.v(TAG,
11129 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011130 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011131 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011132 }
11133 updateOomAdjLocked(r.app);
11134 }
11135 }
11136
11137 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011138 String anrMessage = null;
11139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011140 synchronized(this) {
11141 if (proc.executingServices.size() == 0 || proc.thread == null) {
11142 return;
11143 }
11144 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11145 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11146 ServiceRecord timeout = null;
11147 long nextTime = 0;
11148 while (it.hasNext()) {
11149 ServiceRecord sr = it.next();
11150 if (sr.executingStart < maxTime) {
11151 timeout = sr;
11152 break;
11153 }
11154 if (sr.executingStart > nextTime) {
11155 nextTime = sr.executingStart;
11156 }
11157 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011158 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011159 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011160 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011161 } else {
11162 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11163 msg.obj = proc;
11164 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11165 }
11166 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011167
11168 if (anrMessage != null) {
11169 appNotResponding(proc, null, null, anrMessage);
11170 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011171 }
11172
11173 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011174 // BACKUP AND RESTORE
11175 // =========================================================
11176
11177 // Cause the target app to be launched if necessary and its backup agent
11178 // instantiated. The backup agent will invoke backupAgentCreated() on the
11179 // activity manager to announce its creation.
11180 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011181 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011182 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11183
11184 synchronized(this) {
11185 // !!! TODO: currently no check here that we're already bound
11186 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11187 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11188 synchronized (stats) {
11189 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11190 }
11191
Dianne Hackborne7f97212011-02-24 14:40:20 -080011192 // Backup agent is now in use, its package can't be stopped.
11193 try {
11194 AppGlobals.getPackageManager().setPackageStoppedState(
11195 app.packageName, false);
11196 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011197 } catch (IllegalArgumentException e) {
11198 Slog.w(TAG, "Failed trying to unstop package "
11199 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011200 }
11201
Christopher Tate181fafa2009-05-14 11:12:14 -070011202 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011203 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11204 ? new ComponentName(app.packageName, app.backupAgentName)
11205 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011206 // startProcessLocked() returns existing proc's record if it's already running
11207 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011208 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011209 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011210 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011211 return false;
11212 }
11213
11214 r.app = proc;
11215 mBackupTarget = r;
11216 mBackupAppName = app.packageName;
11217
Christopher Tate6fa95972009-06-05 18:43:55 -070011218 // Try not to kill the process during backup
11219 updateOomAdjLocked(proc);
11220
Christopher Tate181fafa2009-05-14 11:12:14 -070011221 // If the process is already attached, schedule the creation of the backup agent now.
11222 // If it is not yet live, this will be done when it attaches to the framework.
11223 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011224 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011225 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011226 proc.thread.scheduleCreateBackupAgent(app,
11227 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011228 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011229 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011230 }
11231 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011232 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011233 }
11234 // Invariants: at this point, the target app process exists and the application
11235 // is either already running or in the process of coming up. mBackupTarget and
11236 // mBackupAppName describe the app, so that when it binds back to the AM we
11237 // know that it's scheduled for a backup-agent operation.
11238 }
11239
11240 return true;
11241 }
11242
11243 // A backup agent has just come up
11244 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011245 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011246 + " = " + agent);
11247
11248 synchronized(this) {
11249 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011250 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011251 return;
11252 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011253 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011254
Dianne Hackborn06740692010-09-22 22:46:21 -070011255 long oldIdent = Binder.clearCallingIdentity();
11256 try {
11257 IBackupManager bm = IBackupManager.Stub.asInterface(
11258 ServiceManager.getService(Context.BACKUP_SERVICE));
11259 bm.agentConnected(agentPackageName, agent);
11260 } catch (RemoteException e) {
11261 // can't happen; the backup manager service is local
11262 } catch (Exception e) {
11263 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11264 e.printStackTrace();
11265 } finally {
11266 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011267 }
11268 }
11269
11270 // done with this agent
11271 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011272 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011273 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011274 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011275 return;
11276 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011277
11278 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011279 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011280 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011281 return;
11282 }
11283
Christopher Tate181fafa2009-05-14 11:12:14 -070011284 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011285 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011286 return;
11287 }
11288
Christopher Tate6fa95972009-06-05 18:43:55 -070011289 ProcessRecord proc = mBackupTarget.app;
11290 mBackupTarget = null;
11291 mBackupAppName = null;
11292
11293 // Not backing this app up any more; reset its OOM adjustment
11294 updateOomAdjLocked(proc);
11295
Christopher Tatec7b31e32009-06-10 15:49:30 -070011296 // If the app crashed during backup, 'thread' will be null here
11297 if (proc.thread != null) {
11298 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011299 proc.thread.scheduleDestroyBackupAgent(appInfo,
11300 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011301 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011302 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011303 e.printStackTrace();
11304 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011305 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011306 }
11307 }
11308 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011309 // BROADCASTS
11310 // =========================================================
11311
Josh Bartel7f208742010-02-25 11:01:44 -060011312 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011313 List cur) {
11314 final ContentResolver resolver = mContext.getContentResolver();
11315 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11316 if (list == null) {
11317 return cur;
11318 }
11319 int N = list.size();
11320 for (int i=0; i<N; i++) {
11321 Intent intent = list.get(i);
11322 if (filter.match(resolver, intent, true, TAG) >= 0) {
11323 if (cur == null) {
11324 cur = new ArrayList<Intent>();
11325 }
11326 cur.add(intent);
11327 }
11328 }
11329 return cur;
11330 }
11331
11332 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011333 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011334 + mBroadcastsScheduled);
11335
11336 if (mBroadcastsScheduled) {
11337 return;
11338 }
11339 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11340 mBroadcastsScheduled = true;
11341 }
11342
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011343 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011344 IIntentReceiver receiver, IntentFilter filter, String permission) {
11345 synchronized(this) {
11346 ProcessRecord callerApp = null;
11347 if (caller != null) {
11348 callerApp = getRecordForAppLocked(caller);
11349 if (callerApp == null) {
11350 throw new SecurityException(
11351 "Unable to find app for caller " + caller
11352 + " (pid=" + Binder.getCallingPid()
11353 + ") when registering receiver " + receiver);
11354 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011355 if (callerApp.info.uid != Process.SYSTEM_UID &&
11356 !callerApp.pkgList.contains(callerPackage)) {
11357 throw new SecurityException("Given caller package " + callerPackage
11358 + " is not running in process " + callerApp);
11359 }
11360 } else {
11361 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011362 }
11363
11364 List allSticky = null;
11365
11366 // Look for any matching sticky broadcasts...
11367 Iterator actions = filter.actionsIterator();
11368 if (actions != null) {
11369 while (actions.hasNext()) {
11370 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011371 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011372 }
11373 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011374 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011375 }
11376
11377 // The first sticky in the list is returned directly back to
11378 // the client.
11379 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11380
Joe Onorato8a9b2202010-02-26 18:56:32 -080011381 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011382 + ": " + sticky);
11383
11384 if (receiver == null) {
11385 return sticky;
11386 }
11387
11388 ReceiverList rl
11389 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11390 if (rl == null) {
11391 rl = new ReceiverList(this, callerApp,
11392 Binder.getCallingPid(),
11393 Binder.getCallingUid(), receiver);
11394 if (rl.app != null) {
11395 rl.app.receivers.add(rl);
11396 } else {
11397 try {
11398 receiver.asBinder().linkToDeath(rl, 0);
11399 } catch (RemoteException e) {
11400 return sticky;
11401 }
11402 rl.linkedToDeath = true;
11403 }
11404 mRegisteredReceivers.put(receiver.asBinder(), rl);
11405 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011406 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011407 rl.add(bf);
11408 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011409 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011410 }
11411 mReceiverResolver.addFilter(bf);
11412
11413 // Enqueue broadcasts for all existing stickies that match
11414 // this filter.
11415 if (allSticky != null) {
11416 ArrayList receivers = new ArrayList();
11417 receivers.add(bf);
11418
11419 int N = allSticky.size();
11420 for (int i=0; i<N; i++) {
11421 Intent intent = (Intent)allSticky.get(i);
11422 BroadcastRecord r = new BroadcastRecord(intent, null,
11423 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011424 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011425 if (mParallelBroadcasts.size() == 0) {
11426 scheduleBroadcastsLocked();
11427 }
11428 mParallelBroadcasts.add(r);
11429 }
11430 }
11431
11432 return sticky;
11433 }
11434 }
11435
11436 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011437 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011438
11439 boolean doNext = false;
11440
11441 synchronized(this) {
11442 ReceiverList rl
11443 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11444 if (rl != null) {
11445 if (rl.curBroadcast != null) {
11446 BroadcastRecord r = rl.curBroadcast;
11447 doNext = finishReceiverLocked(
11448 receiver.asBinder(), r.resultCode, r.resultData,
11449 r.resultExtras, r.resultAbort, true);
11450 }
11451
11452 if (rl.app != null) {
11453 rl.app.receivers.remove(rl);
11454 }
11455 removeReceiverLocked(rl);
11456 if (rl.linkedToDeath) {
11457 rl.linkedToDeath = false;
11458 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11459 }
11460 }
11461 }
11462
11463 if (!doNext) {
11464 return;
11465 }
11466
11467 final long origId = Binder.clearCallingIdentity();
11468 processNextBroadcast(false);
11469 trimApplications();
11470 Binder.restoreCallingIdentity(origId);
11471 }
11472
11473 void removeReceiverLocked(ReceiverList rl) {
11474 mRegisteredReceivers.remove(rl.receiver.asBinder());
11475 int N = rl.size();
11476 for (int i=0; i<N; i++) {
11477 mReceiverResolver.removeFilter(rl.get(i));
11478 }
11479 }
11480
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011481 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11482 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11483 ProcessRecord r = mLruProcesses.get(i);
11484 if (r.thread != null) {
11485 try {
11486 r.thread.dispatchPackageBroadcast(cmd, packages);
11487 } catch (RemoteException ex) {
11488 }
11489 }
11490 }
11491 }
11492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011493 private final int broadcastIntentLocked(ProcessRecord callerApp,
11494 String callerPackage, Intent intent, String resolvedType,
11495 IIntentReceiver resultTo, int resultCode, String resultData,
11496 Bundle map, String requiredPermission,
11497 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11498 intent = new Intent(intent);
11499
Dianne Hackborne7f97212011-02-24 14:40:20 -080011500 // By default broadcasts do not go to stopped apps.
11501 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11502
Joe Onorato8a9b2202010-02-26 18:56:32 -080011503 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011504 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11505 + " ordered=" + ordered);
11506 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011507 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011508 }
11509
11510 // Handle special intents: if this broadcast is from the package
11511 // manager about a package being removed, we need to remove all of
11512 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011513 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011514 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011515 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11516 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011517 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011518 || uidRemoved) {
11519 if (checkComponentPermission(
11520 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011521 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011522 == PackageManager.PERMISSION_GRANTED) {
11523 if (uidRemoved) {
11524 final Bundle intentExtras = intent.getExtras();
11525 final int uid = intentExtras != null
11526 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11527 if (uid >= 0) {
11528 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11529 synchronized (bs) {
11530 bs.removeUidStatsLocked(uid);
11531 }
11532 }
11533 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011534 // If resources are unvailble just force stop all
11535 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011536 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011537 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11538 if (list != null && (list.length > 0)) {
11539 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011540 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011541 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011542 sendPackageBroadcastLocked(
11543 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011544 }
11545 } else {
11546 Uri data = intent.getData();
11547 String ssp;
11548 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11549 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11550 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011551 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011552 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011553 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011554 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11555 new String[] {ssp});
11556 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011557 }
11558 }
11559 }
11560 } else {
11561 String msg = "Permission Denial: " + intent.getAction()
11562 + " broadcast from " + callerPackage + " (pid=" + callingPid
11563 + ", uid=" + callingUid + ")"
11564 + " requires "
11565 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011566 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011567 throw new SecurityException(msg);
11568 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011569
11570 // Special case for adding a package: by default turn on compatibility
11571 // mode.
11572 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011573 Uri data = intent.getData();
11574 String ssp;
11575 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11576 mCompatModePackages.handlePackageAddedLocked(ssp,
11577 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011578 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011579 }
11580
11581 /*
11582 * If this is the time zone changed action, queue up a message that will reset the timezone
11583 * of all currently running processes. This message will get queued up before the broadcast
11584 * happens.
11585 */
11586 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11587 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11588 }
11589
Robert Greenwalt03595d02010-11-02 14:08:23 -070011590 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11591 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11592 }
11593
Robert Greenwalt434203a2010-10-11 16:00:27 -070011594 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11595 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11596 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11597 }
11598
Dianne Hackborn854060af2009-07-09 18:14:31 -070011599 /*
11600 * Prevent non-system code (defined here to be non-persistent
11601 * processes) from sending protected broadcasts.
11602 */
11603 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11604 || callingUid == Process.SHELL_UID || callingUid == 0) {
11605 // Always okay.
11606 } else if (callerApp == null || !callerApp.persistent) {
11607 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011608 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011609 intent.getAction())) {
11610 String msg = "Permission Denial: not allowed to send broadcast "
11611 + intent.getAction() + " from pid="
11612 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011613 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011614 throw new SecurityException(msg);
11615 }
11616 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011617 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011618 return BROADCAST_SUCCESS;
11619 }
11620 }
11621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011622 // Add to the sticky list if requested.
11623 if (sticky) {
11624 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11625 callingPid, callingUid)
11626 != PackageManager.PERMISSION_GRANTED) {
11627 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11628 + callingPid + ", uid=" + callingUid
11629 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011630 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011631 throw new SecurityException(msg);
11632 }
11633 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011634 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011635 + " and enforce permission " + requiredPermission);
11636 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11637 }
11638 if (intent.getComponent() != null) {
11639 throw new SecurityException(
11640 "Sticky broadcasts can't target a specific component");
11641 }
11642 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11643 if (list == null) {
11644 list = new ArrayList<Intent>();
11645 mStickyBroadcasts.put(intent.getAction(), list);
11646 }
11647 int N = list.size();
11648 int i;
11649 for (i=0; i<N; i++) {
11650 if (intent.filterEquals(list.get(i))) {
11651 // This sticky already exists, replace it.
11652 list.set(i, new Intent(intent));
11653 break;
11654 }
11655 }
11656 if (i >= N) {
11657 list.add(new Intent(intent));
11658 }
11659 }
11660
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011661 // Figure out who all will receive this broadcast.
11662 List receivers = null;
11663 List<BroadcastFilter> registeredReceivers = null;
11664 try {
11665 if (intent.getComponent() != null) {
11666 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011667 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011668 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011669 if (ai != null) {
11670 receivers = new ArrayList();
11671 ResolveInfo ri = new ResolveInfo();
11672 ri.activityInfo = ai;
11673 receivers.add(ri);
11674 }
11675 } else {
11676 // Need to resolve the intent to interested receivers...
11677 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11678 == 0) {
11679 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011680 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011681 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011682 }
Mihai Preda074edef2009-05-18 17:13:31 +020011683 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011684 }
11685 } catch (RemoteException ex) {
11686 // pm is in same process, this will never happen.
11687 }
11688
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011689 final boolean replacePending =
11690 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11691
Joe Onorato8a9b2202010-02-26 18:56:32 -080011692 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011693 + " replacePending=" + replacePending);
11694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011695 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11696 if (!ordered && NR > 0) {
11697 // If we are not serializing this broadcast, then send the
11698 // registered receivers separately so they don't wait for the
11699 // components to be launched.
11700 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11701 callerPackage, callingPid, callingUid, requiredPermission,
11702 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011703 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011704 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011705 TAG, "Enqueueing parallel broadcast " + r
11706 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011707 boolean replaced = false;
11708 if (replacePending) {
11709 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11710 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011711 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011712 "***** DROPPING PARALLEL: " + intent);
11713 mParallelBroadcasts.set(i, r);
11714 replaced = true;
11715 break;
11716 }
11717 }
11718 }
11719 if (!replaced) {
11720 mParallelBroadcasts.add(r);
11721 scheduleBroadcastsLocked();
11722 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011723 registeredReceivers = null;
11724 NR = 0;
11725 }
11726
11727 // Merge into one list.
11728 int ir = 0;
11729 if (receivers != null) {
11730 // A special case for PACKAGE_ADDED: do not allow the package
11731 // being added to see this broadcast. This prevents them from
11732 // using this as a back door to get run as soon as they are
11733 // installed. Maybe in the future we want to have a special install
11734 // broadcast or such for apps, but we'd like to deliberately make
11735 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011736 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011737 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11738 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11739 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011740 Uri data = intent.getData();
11741 if (data != null) {
11742 String pkgName = data.getSchemeSpecificPart();
11743 if (pkgName != null) {
11744 skipPackages = new String[] { pkgName };
11745 }
11746 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011747 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011748 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011749 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011750 if (skipPackages != null && (skipPackages.length > 0)) {
11751 for (String skipPackage : skipPackages) {
11752 if (skipPackage != null) {
11753 int NT = receivers.size();
11754 for (int it=0; it<NT; it++) {
11755 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11756 if (curt.activityInfo.packageName.equals(skipPackage)) {
11757 receivers.remove(it);
11758 it--;
11759 NT--;
11760 }
11761 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011762 }
11763 }
11764 }
11765
11766 int NT = receivers != null ? receivers.size() : 0;
11767 int it = 0;
11768 ResolveInfo curt = null;
11769 BroadcastFilter curr = null;
11770 while (it < NT && ir < NR) {
11771 if (curt == null) {
11772 curt = (ResolveInfo)receivers.get(it);
11773 }
11774 if (curr == null) {
11775 curr = registeredReceivers.get(ir);
11776 }
11777 if (curr.getPriority() >= curt.priority) {
11778 // Insert this broadcast record into the final list.
11779 receivers.add(it, curr);
11780 ir++;
11781 curr = null;
11782 it++;
11783 NT++;
11784 } else {
11785 // Skip to the next ResolveInfo in the final list.
11786 it++;
11787 curt = null;
11788 }
11789 }
11790 }
11791 while (ir < NR) {
11792 if (receivers == null) {
11793 receivers = new ArrayList();
11794 }
11795 receivers.add(registeredReceivers.get(ir));
11796 ir++;
11797 }
11798
11799 if ((receivers != null && receivers.size() > 0)
11800 || resultTo != null) {
11801 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11802 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011803 receivers, resultTo, resultCode, resultData, map, ordered,
11804 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011805 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011806 TAG, "Enqueueing ordered broadcast " + r
11807 + ": prev had " + mOrderedBroadcasts.size());
11808 if (DEBUG_BROADCAST) {
11809 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011810 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011811 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011812 boolean replaced = false;
11813 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011814 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011815 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011816 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011817 "***** DROPPING ORDERED: " + intent);
11818 mOrderedBroadcasts.set(i, r);
11819 replaced = true;
11820 break;
11821 }
11822 }
11823 }
11824 if (!replaced) {
11825 mOrderedBroadcasts.add(r);
11826 scheduleBroadcastsLocked();
11827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011828 }
11829
11830 return BROADCAST_SUCCESS;
11831 }
11832
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011833 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011834 // Refuse possible leaked file descriptors
11835 if (intent != null && intent.hasFileDescriptors() == true) {
11836 throw new IllegalArgumentException("File descriptors passed in Intent");
11837 }
11838
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011839 int flags = intent.getFlags();
11840
11841 if (!mProcessesReady) {
11842 // if the caller really truly claims to know what they're doing, go
11843 // ahead and allow the broadcast without launching any receivers
11844 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11845 intent = new Intent(intent);
11846 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11847 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11848 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11849 + " before boot completion");
11850 throw new IllegalStateException("Cannot broadcast before boot completed");
11851 }
11852 }
11853
11854 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11855 throw new IllegalArgumentException(
11856 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11857 }
11858
11859 return intent;
11860 }
11861
11862 public final int broadcastIntent(IApplicationThread caller,
11863 Intent intent, String resolvedType, IIntentReceiver resultTo,
11864 int resultCode, String resultData, Bundle map,
11865 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011866 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011867 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011868
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011869 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11870 final int callingPid = Binder.getCallingPid();
11871 final int callingUid = Binder.getCallingUid();
11872 final long origId = Binder.clearCallingIdentity();
11873 int res = broadcastIntentLocked(callerApp,
11874 callerApp != null ? callerApp.info.packageName : null,
11875 intent, resolvedType, resultTo,
11876 resultCode, resultData, map, requiredPermission, serialized,
11877 sticky, callingPid, callingUid);
11878 Binder.restoreCallingIdentity(origId);
11879 return res;
11880 }
11881 }
11882
11883 int broadcastIntentInPackage(String packageName, int uid,
11884 Intent intent, String resolvedType, IIntentReceiver resultTo,
11885 int resultCode, String resultData, Bundle map,
11886 String requiredPermission, boolean serialized, boolean sticky) {
11887 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011888 intent = verifyBroadcastLocked(intent);
11889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011890 final long origId = Binder.clearCallingIdentity();
11891 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11892 resultTo, resultCode, resultData, map, requiredPermission,
11893 serialized, sticky, -1, uid);
11894 Binder.restoreCallingIdentity(origId);
11895 return res;
11896 }
11897 }
11898
11899 public final void unbroadcastIntent(IApplicationThread caller,
11900 Intent intent) {
11901 // Refuse possible leaked file descriptors
11902 if (intent != null && intent.hasFileDescriptors() == true) {
11903 throw new IllegalArgumentException("File descriptors passed in Intent");
11904 }
11905
11906 synchronized(this) {
11907 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11908 != PackageManager.PERMISSION_GRANTED) {
11909 String msg = "Permission Denial: unbroadcastIntent() from pid="
11910 + Binder.getCallingPid()
11911 + ", uid=" + Binder.getCallingUid()
11912 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011913 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011914 throw new SecurityException(msg);
11915 }
11916 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11917 if (list != null) {
11918 int N = list.size();
11919 int i;
11920 for (i=0; i<N; i++) {
11921 if (intent.filterEquals(list.get(i))) {
11922 list.remove(i);
11923 break;
11924 }
11925 }
11926 }
11927 }
11928 }
11929
11930 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11931 String resultData, Bundle resultExtras, boolean resultAbort,
11932 boolean explicit) {
11933 if (mOrderedBroadcasts.size() == 0) {
11934 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011935 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011936 }
11937 return false;
11938 }
11939 BroadcastRecord r = mOrderedBroadcasts.get(0);
11940 if (r.receiver == null) {
11941 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011942 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011943 }
11944 return false;
11945 }
11946 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011947 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011948 return false;
11949 }
11950 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011951 r.state = BroadcastRecord.IDLE;
11952 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011953 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011954 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011955 }
11956 }
11957 r.receiver = null;
11958 r.intent.setComponent(null);
11959 if (r.curApp != null) {
11960 r.curApp.curReceiver = null;
11961 }
11962 if (r.curFilter != null) {
11963 r.curFilter.receiverList.curBroadcast = null;
11964 }
11965 r.curFilter = null;
11966 r.curApp = null;
11967 r.curComponent = null;
11968 r.curReceiver = null;
11969 mPendingBroadcast = null;
11970
11971 r.resultCode = resultCode;
11972 r.resultData = resultData;
11973 r.resultExtras = resultExtras;
11974 r.resultAbort = resultAbort;
11975
11976 // We will process the next receiver right now if this is finishing
11977 // an app receiver (which is always asynchronous) or after we have
11978 // come back from calling a receiver.
11979 return state == BroadcastRecord.APP_RECEIVE
11980 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11981 }
11982
11983 public void finishReceiver(IBinder who, int resultCode, String resultData,
11984 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011985 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011986
11987 // Refuse possible leaked file descriptors
11988 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11989 throw new IllegalArgumentException("File descriptors passed in Bundle");
11990 }
11991
11992 boolean doNext;
11993
11994 final long origId = Binder.clearCallingIdentity();
11995
11996 synchronized(this) {
11997 doNext = finishReceiverLocked(
11998 who, resultCode, resultData, resultExtras, resultAbort, true);
11999 }
12000
12001 if (doNext) {
12002 processNextBroadcast(false);
12003 }
12004 trimApplications();
12005
12006 Binder.restoreCallingIdentity(origId);
12007 }
12008
Jeff Brown4d94a762010-09-23 11:33:28 -070012009 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012010 if (r.nextReceiver > 0) {
12011 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12012 if (curReceiver instanceof BroadcastFilter) {
12013 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012014 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012015 System.identityHashCode(r),
12016 r.intent.getAction(),
12017 r.nextReceiver - 1,
12018 System.identityHashCode(bf));
12019 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012020 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012021 System.identityHashCode(r),
12022 r.intent.getAction(),
12023 r.nextReceiver - 1,
12024 ((ResolveInfo)curReceiver).toString());
12025 }
12026 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012027 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012028 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012029 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012030 System.identityHashCode(r),
12031 r.intent.getAction(),
12032 r.nextReceiver,
12033 "NONE");
12034 }
12035 }
12036
Jeff Brown4d94a762010-09-23 11:33:28 -070012037 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12038 if (! mPendingBroadcastTimeoutMessage) {
12039 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12040 mHandler.sendMessageAtTime(msg, timeoutTime);
12041 mPendingBroadcastTimeoutMessage = true;
12042 }
12043 }
12044
12045 private final void cancelBroadcastTimeoutLocked() {
12046 if (mPendingBroadcastTimeoutMessage) {
12047 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12048 mPendingBroadcastTimeoutMessage = false;
12049 }
12050 }
12051
12052 private final void broadcastTimeoutLocked(boolean fromMsg) {
12053 if (fromMsg) {
12054 mPendingBroadcastTimeoutMessage = false;
12055 }
12056
12057 if (mOrderedBroadcasts.size() == 0) {
12058 return;
12059 }
12060
12061 long now = SystemClock.uptimeMillis();
12062 BroadcastRecord r = mOrderedBroadcasts.get(0);
12063 if (fromMsg) {
12064 if (mDidDexOpt) {
12065 // Delay timeouts until dexopt finishes.
12066 mDidDexOpt = false;
12067 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12068 setBroadcastTimeoutLocked(timeoutTime);
12069 return;
12070 }
12071 if (! mProcessesReady) {
12072 // Only process broadcast timeouts if the system is ready. That way
12073 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12074 // to do heavy lifting for system up.
12075 return;
12076 }
12077
12078 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12079 if (timeoutTime > now) {
12080 // We can observe premature timeouts because we do not cancel and reset the
12081 // broadcast timeout message after each receiver finishes. Instead, we set up
12082 // an initial timeout then kick it down the road a little further as needed
12083 // when it expires.
12084 if (DEBUG_BROADCAST) Slog.v(TAG,
12085 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12086 + timeoutTime);
12087 setBroadcastTimeoutLocked(timeoutTime);
12088 return;
12089 }
12090 }
12091
12092 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12093 + ", started " + (now - r.receiverTime) + "ms ago");
12094 r.receiverTime = now;
12095 r.anrCount++;
12096
12097 // Current receiver has passed its expiration date.
12098 if (r.nextReceiver <= 0) {
12099 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12100 return;
12101 }
12102
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012103 ProcessRecord app = null;
12104 String anrMessage = null;
12105
Jeff Brown4d94a762010-09-23 11:33:28 -070012106 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12107 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12108 logBroadcastReceiverDiscardLocked(r);
12109 if (curReceiver instanceof BroadcastFilter) {
12110 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12111 if (bf.receiverList.pid != 0
12112 && bf.receiverList.pid != MY_PID) {
12113 synchronized (this.mPidsSelfLocked) {
12114 app = this.mPidsSelfLocked.get(
12115 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012116 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012117 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012118 } else {
12119 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012120 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012121
Jeff Brown4d94a762010-09-23 11:33:28 -070012122 if (app != null) {
12123 anrMessage = "Broadcast of " + r.intent.toString();
12124 }
12125
12126 if (mPendingBroadcast == r) {
12127 mPendingBroadcast = null;
12128 }
12129
12130 // Move on to the next receiver.
12131 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12132 r.resultExtras, r.resultAbort, true);
12133 scheduleBroadcastsLocked();
12134
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012135 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012136 // Post the ANR to the handler since we do not want to process ANRs while
12137 // potentially holding our lock.
12138 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012139 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012140 }
12141
12142 private final void processCurBroadcastLocked(BroadcastRecord r,
12143 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012144 if (DEBUG_BROADCAST) Slog.v(TAG,
12145 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012146 if (app.thread == null) {
12147 throw new RemoteException();
12148 }
12149 r.receiver = app.thread.asBinder();
12150 r.curApp = app;
12151 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012152 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012153
12154 // Tell the application to launch this receiver.
12155 r.intent.setComponent(r.curComponent);
12156
12157 boolean started = false;
12158 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012159 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012160 "Delivering to component " + r.curComponent
12161 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012162 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012163 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012164 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012165 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012166 if (DEBUG_BROADCAST) Slog.v(TAG,
12167 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012168 started = true;
12169 } finally {
12170 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012171 if (DEBUG_BROADCAST) Slog.v(TAG,
12172 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012173 r.receiver = null;
12174 r.curApp = null;
12175 app.curReceiver = null;
12176 }
12177 }
12178
12179 }
12180
Jeff Brown4d94a762010-09-23 11:33:28 -070012181 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012182 Intent intent, int resultCode, String data, Bundle extras,
12183 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012184 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012185 if (app != null && app.thread != null) {
12186 // If we have an app thread, do the call through that so it is
12187 // correctly ordered with other one-way calls.
12188 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012189 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012190 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012191 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012192 }
12193 }
12194
Jeff Brown4d94a762010-09-23 11:33:28 -070012195 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196 BroadcastFilter filter, boolean ordered) {
12197 boolean skip = false;
12198 if (filter.requiredPermission != null) {
12199 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012200 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012201 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012202 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012203 + r.intent.toString()
12204 + " from " + r.callerPackage + " (pid="
12205 + r.callingPid + ", uid=" + r.callingUid + ")"
12206 + " requires " + filter.requiredPermission
12207 + " due to registered receiver " + filter);
12208 skip = true;
12209 }
12210 }
12211 if (r.requiredPermission != null) {
12212 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012213 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012214 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012215 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012216 + r.intent.toString()
12217 + " to " + filter.receiverList.app
12218 + " (pid=" + filter.receiverList.pid
12219 + ", uid=" + filter.receiverList.uid + ")"
12220 + " requires " + r.requiredPermission
12221 + " due to sender " + r.callerPackage
12222 + " (uid " + r.callingUid + ")");
12223 skip = true;
12224 }
12225 }
12226
12227 if (!skip) {
12228 // If this is not being sent as an ordered broadcast, then we
12229 // don't want to touch the fields that keep track of the current
12230 // state of ordered broadcasts.
12231 if (ordered) {
12232 r.receiver = filter.receiverList.receiver.asBinder();
12233 r.curFilter = filter;
12234 filter.receiverList.curBroadcast = r;
12235 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012236 if (filter.receiverList.app != null) {
12237 // Bump hosting application to no longer be in background
12238 // scheduling class. Note that we can't do that if there
12239 // isn't an app... but we can only be in that case for
12240 // things that directly call the IActivityManager API, which
12241 // are already core system stuff so don't matter for this.
12242 r.curApp = filter.receiverList.app;
12243 filter.receiverList.app.curReceiver = r;
12244 updateOomAdjLocked();
12245 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012246 }
12247 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012248 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012249 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012250 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012251 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012252 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012253 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012254 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012255 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012256 if (ordered) {
12257 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12258 }
12259 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012260 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012261 if (ordered) {
12262 r.receiver = null;
12263 r.curFilter = null;
12264 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012265 if (filter.receiverList.app != null) {
12266 filter.receiverList.app.curReceiver = null;
12267 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012268 }
12269 }
12270 }
12271 }
12272
Dianne Hackborn12527f92009-11-11 17:39:50 -080012273 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12274 if (r.callingUid < 0) {
12275 // This was from a registerReceiver() call; ignore it.
12276 return;
12277 }
12278 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12279 MAX_BROADCAST_HISTORY-1);
12280 r.finishTime = SystemClock.uptimeMillis();
12281 mBroadcastHistory[0] = r;
12282 }
12283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012284 private final void processNextBroadcast(boolean fromMsg) {
12285 synchronized(this) {
12286 BroadcastRecord r;
12287
Joe Onorato8a9b2202010-02-26 18:56:32 -080012288 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012289 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012290 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012291
12292 updateCpuStats();
12293
12294 if (fromMsg) {
12295 mBroadcastsScheduled = false;
12296 }
12297
12298 // First, deliver any non-serialized broadcasts right away.
12299 while (mParallelBroadcasts.size() > 0) {
12300 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012301 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012302 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012303 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012304 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012305 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012306 for (int i=0; i<N; i++) {
12307 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012308 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012309 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012310 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012311 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012312 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012313 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012314 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012315 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012316 }
12317
12318 // Now take care of the next serialized one...
12319
12320 // If we are waiting for a process to come up to handle the next
12321 // broadcast, then do nothing at this point. Just in case, we
12322 // check that the process we're waiting for still exists.
12323 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012324 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012325 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012326 + mPendingBroadcast.curApp);
12327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012328
12329 boolean isDead;
12330 synchronized (mPidsSelfLocked) {
12331 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12332 }
12333 if (!isDead) {
12334 // It's still alive, so keep waiting
12335 return;
12336 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012337 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012338 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012339 mPendingBroadcast.state = BroadcastRecord.IDLE;
12340 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012341 mPendingBroadcast = null;
12342 }
12343 }
12344
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012345 boolean looped = false;
12346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012347 do {
12348 if (mOrderedBroadcasts.size() == 0) {
12349 // No more broadcasts pending, so all done!
12350 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012351 if (looped) {
12352 // If we had finished the last ordered broadcast, then
12353 // make sure all processes have correct oom and sched
12354 // adjustments.
12355 updateOomAdjLocked();
12356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012357 return;
12358 }
12359 r = mOrderedBroadcasts.get(0);
12360 boolean forceReceive = false;
12361
12362 // Ensure that even if something goes awry with the timeout
12363 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012364 // and continue to make progress.
12365 //
12366 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012367 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012368 // one time heavy lifting after system upgrades and can take
12369 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012370 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012371 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012372 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012373 if ((numReceivers > 0) &&
12374 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012375 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012376 + " now=" + now
12377 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012378 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012379 + " intent=" + r.intent
12380 + " numReceivers=" + numReceivers
12381 + " nextReceiver=" + r.nextReceiver
12382 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012383 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012384 forceReceive = true;
12385 r.state = BroadcastRecord.IDLE;
12386 }
12387 }
12388
12389 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012390 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012391 "processNextBroadcast() called when not idle (state="
12392 + r.state + ")");
12393 return;
12394 }
12395
12396 if (r.receivers == null || r.nextReceiver >= numReceivers
12397 || r.resultAbort || forceReceive) {
12398 // No more receivers for this broadcast! Send the final
12399 // result if requested...
12400 if (r.resultTo != null) {
12401 try {
12402 if (DEBUG_BROADCAST) {
12403 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012404 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012405 + " seq=" + seq + " app=" + r.callerApp);
12406 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012407 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012408 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012409 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012410 // Set this to null so that the reference
12411 // (local and remote) isnt kept in the mBroadcastHistory.
12412 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012413 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012414 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012415 }
12416 }
12417
Joe Onorato8a9b2202010-02-26 18:56:32 -080012418 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012419 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012420
Joe Onorato8a9b2202010-02-26 18:56:32 -080012421 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012422 + r);
12423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012424 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012425 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012426 mOrderedBroadcasts.remove(0);
12427 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012428 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012429 continue;
12430 }
12431 } while (r == null);
12432
12433 // Get the next receiver...
12434 int recIdx = r.nextReceiver++;
12435
12436 // Keep track of when this receiver started, and make sure there
12437 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012438 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012439 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012440 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012441 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012442 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012443 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012444 }
12445 if (! mPendingBroadcastTimeoutMessage) {
12446 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012447 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012448 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12449 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012450 }
12451
12452 Object nextReceiver = r.receivers.get(recIdx);
12453 if (nextReceiver instanceof BroadcastFilter) {
12454 // Simple case: this is a registered receiver who gets
12455 // a direct call.
12456 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012457 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012458 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012459 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012460 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012461 if (r.receiver == null || !r.ordered) {
12462 // The receiver has already finished, so schedule to
12463 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012464 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12465 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012466 r.state = BroadcastRecord.IDLE;
12467 scheduleBroadcastsLocked();
12468 }
12469 return;
12470 }
12471
12472 // Hard case: need to instantiate the receiver, possibly
12473 // starting its application process to host it.
12474
12475 ResolveInfo info =
12476 (ResolveInfo)nextReceiver;
12477
12478 boolean skip = false;
12479 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012480 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12481 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012482 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012483 if (!info.activityInfo.exported) {
12484 Slog.w(TAG, "Permission Denial: broadcasting "
12485 + r.intent.toString()
12486 + " from " + r.callerPackage + " (pid=" + r.callingPid
12487 + ", uid=" + r.callingUid + ")"
12488 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12489 + " due to receiver " + info.activityInfo.packageName
12490 + "/" + info.activityInfo.name);
12491 } else {
12492 Slog.w(TAG, "Permission Denial: broadcasting "
12493 + r.intent.toString()
12494 + " from " + r.callerPackage + " (pid=" + r.callingPid
12495 + ", uid=" + r.callingUid + ")"
12496 + " requires " + info.activityInfo.permission
12497 + " due to receiver " + info.activityInfo.packageName
12498 + "/" + info.activityInfo.name);
12499 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012500 skip = true;
12501 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012502 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012503 r.requiredPermission != null) {
12504 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012505 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012506 checkPermission(r.requiredPermission,
12507 info.activityInfo.applicationInfo.packageName);
12508 } catch (RemoteException e) {
12509 perm = PackageManager.PERMISSION_DENIED;
12510 }
12511 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012512 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012513 + r.intent + " to "
12514 + info.activityInfo.applicationInfo.packageName
12515 + " requires " + r.requiredPermission
12516 + " due to sender " + r.callerPackage
12517 + " (uid " + r.callingUid + ")");
12518 skip = true;
12519 }
12520 }
12521 if (r.curApp != null && r.curApp.crashing) {
12522 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012523 if (DEBUG_BROADCAST) Slog.v(TAG,
12524 "Skipping deliver ordered " + r + " to " + r.curApp
12525 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012526 skip = true;
12527 }
12528
12529 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012530 if (DEBUG_BROADCAST) Slog.v(TAG,
12531 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012532 r.receiver = null;
12533 r.curFilter = null;
12534 r.state = BroadcastRecord.IDLE;
12535 scheduleBroadcastsLocked();
12536 return;
12537 }
12538
12539 r.state = BroadcastRecord.APP_RECEIVE;
12540 String targetProcess = info.activityInfo.processName;
12541 r.curComponent = new ComponentName(
12542 info.activityInfo.applicationInfo.packageName,
12543 info.activityInfo.name);
12544 r.curReceiver = info.activityInfo;
12545
Dianne Hackborne7f97212011-02-24 14:40:20 -080012546 // Broadcast is being executed, its package can't be stopped.
12547 try {
12548 AppGlobals.getPackageManager().setPackageStoppedState(
12549 r.curComponent.getPackageName(), false);
12550 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012551 } catch (IllegalArgumentException e) {
12552 Slog.w(TAG, "Failed trying to unstop package "
12553 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012554 }
12555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012556 // Is this receiver's application already running?
12557 ProcessRecord app = getProcessRecordLocked(targetProcess,
12558 info.activityInfo.applicationInfo.uid);
12559 if (app != null && app.thread != null) {
12560 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012561 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012562 processCurBroadcastLocked(r, app);
12563 return;
12564 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012565 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012566 + r.curComponent, e);
12567 }
12568
12569 // If a dead object exception was thrown -- fall through to
12570 // restart the application.
12571 }
12572
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012573 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012574 if (DEBUG_BROADCAST) Slog.v(TAG,
12575 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012576 if ((r.curApp=startProcessLocked(targetProcess,
12577 info.activityInfo.applicationInfo, true,
12578 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012579 "broadcast", r.curComponent,
12580 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12581 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012582 // Ah, this recipient is unavailable. Finish it if necessary,
12583 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012584 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012585 + info.activityInfo.applicationInfo.packageName + "/"
12586 + info.activityInfo.applicationInfo.uid + " for broadcast "
12587 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012588 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012589 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12590 r.resultExtras, r.resultAbort, true);
12591 scheduleBroadcastsLocked();
12592 r.state = BroadcastRecord.IDLE;
12593 return;
12594 }
12595
12596 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012597 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012598 }
12599 }
12600
12601 // =========================================================
12602 // INSTRUMENTATION
12603 // =========================================================
12604
12605 public boolean startInstrumentation(ComponentName className,
12606 String profileFile, int flags, Bundle arguments,
12607 IInstrumentationWatcher watcher) {
12608 // Refuse possible leaked file descriptors
12609 if (arguments != null && arguments.hasFileDescriptors()) {
12610 throw new IllegalArgumentException("File descriptors passed in Bundle");
12611 }
12612
12613 synchronized(this) {
12614 InstrumentationInfo ii = null;
12615 ApplicationInfo ai = null;
12616 try {
12617 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012618 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012619 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012620 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012621 } catch (PackageManager.NameNotFoundException e) {
12622 }
12623 if (ii == null) {
12624 reportStartInstrumentationFailure(watcher, className,
12625 "Unable to find instrumentation info for: " + className);
12626 return false;
12627 }
12628 if (ai == null) {
12629 reportStartInstrumentationFailure(watcher, className,
12630 "Unable to find instrumentation target package: " + ii.targetPackage);
12631 return false;
12632 }
12633
12634 int match = mContext.getPackageManager().checkSignatures(
12635 ii.targetPackage, ii.packageName);
12636 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12637 String msg = "Permission Denial: starting instrumentation "
12638 + className + " from pid="
12639 + Binder.getCallingPid()
12640 + ", uid=" + Binder.getCallingPid()
12641 + " not allowed because package " + ii.packageName
12642 + " does not have a signature matching the target "
12643 + ii.targetPackage;
12644 reportStartInstrumentationFailure(watcher, className, msg);
12645 throw new SecurityException(msg);
12646 }
12647
12648 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012649 // Instrumentation can kill and relaunch even persistent processes
12650 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012651 ProcessRecord app = addAppLocked(ai);
12652 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012653 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012654 app.instrumentationProfileFile = profileFile;
12655 app.instrumentationArguments = arguments;
12656 app.instrumentationWatcher = watcher;
12657 app.instrumentationResultClass = className;
12658 Binder.restoreCallingIdentity(origId);
12659 }
12660
12661 return true;
12662 }
12663
12664 /**
12665 * Report errors that occur while attempting to start Instrumentation. Always writes the
12666 * error to the logs, but if somebody is watching, send the report there too. This enables
12667 * the "am" command to report errors with more information.
12668 *
12669 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12670 * @param cn The component name of the instrumentation.
12671 * @param report The error report.
12672 */
12673 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12674 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012675 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012676 try {
12677 if (watcher != null) {
12678 Bundle results = new Bundle();
12679 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12680 results.putString("Error", report);
12681 watcher.instrumentationStatus(cn, -1, results);
12682 }
12683 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012684 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012685 }
12686 }
12687
12688 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12689 if (app.instrumentationWatcher != null) {
12690 try {
12691 // NOTE: IInstrumentationWatcher *must* be oneway here
12692 app.instrumentationWatcher.instrumentationFinished(
12693 app.instrumentationClass,
12694 resultCode,
12695 results);
12696 } catch (RemoteException e) {
12697 }
12698 }
12699 app.instrumentationWatcher = null;
12700 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012701 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012702 app.instrumentationProfileFile = null;
12703 app.instrumentationArguments = null;
12704
Christopher Tate3dacd842011-08-19 14:56:15 -070012705 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012706 }
12707
12708 public void finishInstrumentation(IApplicationThread target,
12709 int resultCode, Bundle results) {
12710 // Refuse possible leaked file descriptors
12711 if (results != null && results.hasFileDescriptors()) {
12712 throw new IllegalArgumentException("File descriptors passed in Intent");
12713 }
12714
12715 synchronized(this) {
12716 ProcessRecord app = getRecordForAppLocked(target);
12717 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012718 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012719 return;
12720 }
12721 final long origId = Binder.clearCallingIdentity();
12722 finishInstrumentationLocked(app, resultCode, results);
12723 Binder.restoreCallingIdentity(origId);
12724 }
12725 }
12726
12727 // =========================================================
12728 // CONFIGURATION
12729 // =========================================================
12730
12731 public ConfigurationInfo getDeviceConfigurationInfo() {
12732 ConfigurationInfo config = new ConfigurationInfo();
12733 synchronized (this) {
12734 config.reqTouchScreen = mConfiguration.touchscreen;
12735 config.reqKeyboardType = mConfiguration.keyboard;
12736 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012737 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12738 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012739 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12740 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012741 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12742 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012743 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12744 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012745 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012746 }
12747 return config;
12748 }
12749
12750 public Configuration getConfiguration() {
12751 Configuration ci;
12752 synchronized(this) {
12753 ci = new Configuration(mConfiguration);
12754 }
12755 return ci;
12756 }
12757
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012758 public void updatePersistentConfiguration(Configuration values) {
12759 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12760 "updateConfiguration()");
12761 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12762 "updateConfiguration()");
12763 if (values == null) {
12764 throw new NullPointerException("Configuration must not be null");
12765 }
12766
12767 synchronized(this) {
12768 final long origId = Binder.clearCallingIdentity();
12769 updateConfigurationLocked(values, null, true);
12770 Binder.restoreCallingIdentity(origId);
12771 }
12772 }
12773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012774 public void updateConfiguration(Configuration values) {
12775 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12776 "updateConfiguration()");
12777
12778 synchronized(this) {
12779 if (values == null && mWindowManager != null) {
12780 // sentinel: fetch the current configuration from the window manager
12781 values = mWindowManager.computeNewConfiguration();
12782 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012783
12784 if (mWindowManager != null) {
12785 mProcessList.applyDisplaySize(mWindowManager);
12786 }
12787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012788 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012789 if (values != null) {
12790 Settings.System.clearConfiguration(values);
12791 }
12792 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012793 Binder.restoreCallingIdentity(origId);
12794 }
12795 }
12796
12797 /**
12798 * Do either or both things: (1) change the current configuration, and (2)
12799 * make sure the given activity is running with the (now) current
12800 * configuration. Returns true if the activity has been left running, or
12801 * false if <var>starting</var> is being destroyed to match the new
12802 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012803 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012804 */
12805 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012806 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012807 int changes = 0;
12808
12809 boolean kept = true;
12810
12811 if (values != null) {
12812 Configuration newConfig = new Configuration(mConfiguration);
12813 changes = newConfig.updateFrom(values);
12814 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012815 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012816 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012817 }
12818
Doug Zongker2bec3d42009-12-04 12:52:44 -080012819 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012820
12821 if (values.locale != null) {
12822 saveLocaleLocked(values.locale,
12823 !values.locale.equals(mConfiguration.locale),
12824 values.userSetLocale);
12825 }
12826
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012827 mConfigurationSeq++;
12828 if (mConfigurationSeq <= 0) {
12829 mConfigurationSeq = 1;
12830 }
12831 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012832 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012833 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012834
12835 AttributeCache ac = AttributeCache.instance();
12836 if (ac != null) {
12837 ac.updateConfiguration(mConfiguration);
12838 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012839
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012840 // Make sure all resources in our process are updated
12841 // right now, so that anyone who is going to retrieve
12842 // resource values after we return will be sure to get
12843 // the new ones. This is especially important during
12844 // boot, where the first config change needs to guarantee
12845 // all resources have that config before following boot
12846 // code is executed.
12847 mSystemThread.applyConfigurationToResources(newConfig);
12848
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012849 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012850 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12851 msg.obj = new Configuration(mConfiguration);
12852 mHandler.sendMessage(msg);
12853 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012854
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012855 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12856 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012857 try {
12858 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012859 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012860 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012861 app.thread.scheduleConfigurationChanged(mConfiguration);
12862 }
12863 } catch (Exception e) {
12864 }
12865 }
12866 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012867 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12868 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012869 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12870 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012871 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12872 broadcastIntentLocked(null, null,
12873 new Intent(Intent.ACTION_LOCALE_CHANGED),
12874 null, null, 0, null, null,
12875 null, false, false, MY_PID, Process.SYSTEM_UID);
12876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012877 }
12878 }
12879
12880 if (changes != 0 && starting == null) {
12881 // If the configuration changed, and the caller is not already
12882 // in the process of starting an activity, then find the top
12883 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012884 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012885 }
12886
12887 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012888 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012889 // And we need to make sure at this point that all other activities
12890 // are made visible with the correct configuration.
12891 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012892 }
12893
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012894 if (values != null && mWindowManager != null) {
12895 mWindowManager.setNewConfiguration(mConfiguration);
12896 }
12897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012898 return kept;
12899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012900
12901 /**
12902 * Save the locale. You must be inside a synchronized (this) block.
12903 */
12904 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12905 if(isDiff) {
12906 SystemProperties.set("user.language", l.getLanguage());
12907 SystemProperties.set("user.region", l.getCountry());
12908 }
12909
12910 if(isPersist) {
12911 SystemProperties.set("persist.sys.language", l.getLanguage());
12912 SystemProperties.set("persist.sys.country", l.getCountry());
12913 SystemProperties.set("persist.sys.localevar", l.getVariant());
12914 }
12915 }
12916
12917 // =========================================================
12918 // LIFETIME MANAGEMENT
12919 // =========================================================
12920
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012921 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12922 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012923 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012924 // This adjustment has already been computed. If we are calling
12925 // from the top, we may have already computed our adjustment with
12926 // an earlier hidden adjustment that isn't really for us... if
12927 // so, use the new hidden adjustment.
12928 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012929 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012930 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012931 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012932 }
12933
12934 if (app.thread == null) {
12935 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012936 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012937 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012938 }
12939
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012940 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12941 app.adjSource = null;
12942 app.adjTarget = null;
12943 app.empty = false;
12944 app.hidden = false;
12945
12946 final int activitiesSize = app.activities.size();
12947
Dianne Hackborn7d608422011-08-07 16:24:18 -070012948 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012949 // The max adjustment doesn't allow this app to be anything
12950 // below foreground, so it is not worth doing work for it.
12951 app.adjType = "fixed";
12952 app.adjSeq = mAdjSeq;
12953 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012954 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012955 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012956 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012957 // System process can do UI, and when they do we want to have
12958 // them trim their memory after the user leaves the UI. To
12959 // facilitate this, here we need to determine whether or not it
12960 // is currently showing UI.
12961 app.systemNoUi = true;
12962 if (app == TOP_APP) {
12963 app.systemNoUi = false;
12964 } else if (activitiesSize > 0) {
12965 for (int j = 0; j < activitiesSize; j++) {
12966 final ActivityRecord r = app.activities.get(j);
12967 if (r.visible) {
12968 app.systemNoUi = false;
12969 break;
12970 }
12971 }
12972 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012973 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012974 }
12975
12976 final boolean hadForegroundActivities = app.foregroundActivities;
12977
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012978 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012979 app.keeping = false;
12980 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012981
The Android Open Source Project4df24232009-03-05 14:34:35 -080012982 // Determine the importance of the process, starting with most
12983 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012984 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012985 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012986 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012987 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012988 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012989 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012990 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012991 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012992 } else if (app.instrumentationClass != null) {
12993 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012994 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012995 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012996 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012997 } else if (app.curReceiver != null ||
12998 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12999 // An app that is currently receiving a broadcast also
13000 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013001 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013002 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013003 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013004 } else if (app.executingServices.size() > 0) {
13005 // An app that is currently executing a service callback also
13006 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013007 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013008 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013009 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013010 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013011 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013012 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013013 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013014 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013015 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013016 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013017 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013018 // A very not-needed process. If this is lower in the lru list,
13019 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013020 adj = hiddenAdj;
13021 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013022 app.hidden = true;
13023 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013024 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013025 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013026
13027 // Examine all activities if not already foreground.
13028 if (!app.foregroundActivities && activitiesSize > 0) {
13029 for (int j = 0; j < activitiesSize; j++) {
13030 final ActivityRecord r = app.activities.get(j);
13031 if (r.visible) {
13032 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013033 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13034 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013035 app.adjType = "visible";
13036 }
13037 schedGroup = Process.THREAD_GROUP_DEFAULT;
13038 app.hidden = false;
13039 app.foregroundActivities = true;
13040 break;
13041 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13042 || r.state == ActivityState.STOPPING) {
13043 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013044 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13045 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013046 app.adjType = "stopping";
13047 }
13048 app.foregroundActivities = true;
13049 }
13050 }
13051 }
13052
Dianne Hackborn7d608422011-08-07 16:24:18 -070013053 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013054 if (app.foregroundServices) {
13055 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013056 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013057 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013058 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013059 } else if (app.forcingToForeground != null) {
13060 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013061 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013062 app.adjType = "force-foreground";
13063 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013064 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013065 }
13066 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013067
Dianne Hackborn7d608422011-08-07 16:24:18 -070013068 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013069 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013070 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013071 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13072 app.adjType = "heavy";
13073 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013074
Dianne Hackborn7d608422011-08-07 16:24:18 -070013075 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013076 // This process is hosting what we currently consider to be the
13077 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013078 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013079 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13080 app.adjType = "home";
13081 }
13082
Joe Onorato8a9b2202010-02-26 18:56:32 -080013083 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013084
The Android Open Source Project4df24232009-03-05 14:34:35 -080013085 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013086 // there are applications dependent on our services or providers, but
13087 // this gives us a baseline and makes sure we don't get into an
13088 // infinite recursion.
13089 app.adjSeq = mAdjSeq;
13090 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013091
Christopher Tate6fa95972009-06-05 18:43:55 -070013092 if (mBackupTarget != null && app == mBackupTarget.app) {
13093 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013094 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013095 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013096 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013097 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013098 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013099 }
13100 }
13101
Dianne Hackborn7d608422011-08-07 16:24:18 -070013102 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013103 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013104 final long now = SystemClock.uptimeMillis();
13105 // This process is more important if the top activity is
13106 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013107 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013108 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013109 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013110 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013111 if (app.hasShownUi) {
13112 // If this process has shown some UI, let it immediately
13113 // go to the LRU list because it may be pretty heavy with
13114 // UI stuff. We'll tag it with a label just to help
13115 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013116 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013117 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013118 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013119 } else {
13120 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13121 // This service has seen some activity within
13122 // recent memory, so we will keep its process ahead
13123 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013124 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
13125 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013126 app.adjType = "started-services";
13127 app.hidden = false;
13128 }
13129 }
13130 // If we have let the service slide into the background
13131 // state, still have some text describing what it is doing
13132 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013133 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013134 app.adjType = "started-bg-services";
13135 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013136 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013137 // Don't kill this process because it is doing work; it
13138 // has said it is doing work.
13139 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013140 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013141 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013142 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013143 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013144 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013145 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013146 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013147 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013148 // XXX should compute this based on the max of
13149 // all connected clients.
13150 ConnectionRecord cr = clist.get(i);
13151 if (cr.binding.client == app) {
13152 // Binding to ourself is not interesting.
13153 continue;
13154 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013155 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013156 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013157 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013158 int myHiddenAdj = hiddenAdj;
13159 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013160 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013161 myHiddenAdj = client.hiddenAdj;
13162 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013163 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013164 }
13165 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013166 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013167 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013168 String adjType = null;
13169 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13170 // Not doing bind OOM management, so treat
13171 // this guy more like a started service.
13172 if (app.hasShownUi) {
13173 // If this process has shown some UI, let it immediately
13174 // go to the LRU list because it may be pretty heavy with
13175 // UI stuff. We'll tag it with a label just to help
13176 // debug and understand what is going on.
13177 if (adj > clientAdj) {
13178 adjType = "bound-bg-ui-services";
13179 }
13180 clientAdj = adj;
13181 } else {
13182 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13183 // This service has not seen activity within
13184 // recent memory, so allow it to drop to the
13185 // LRU list if there is no other reason to keep
13186 // it around. We'll also tag it with a label just
13187 // to help debug and undertand what is going on.
13188 if (adj > clientAdj) {
13189 adjType = "bound-bg-services";
13190 }
13191 clientAdj = adj;
13192 }
13193 }
13194 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013195 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013196 // If this process has recently shown UI, and
13197 // the process that is binding to it is less
13198 // important than being visible, then we don't
13199 // care about the binding as much as we care
13200 // about letting this process get into the LRU
13201 // list to be killed and restarted if needed for
13202 // memory.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013203 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013204 adjType = "bound-bg-ui-services";
13205 } else {
13206 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13207 |Context.BIND_IMPORTANT)) != 0) {
13208 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013209 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013210 adj = clientAdj;
13211 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013212 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013213 }
13214 if (!client.hidden) {
13215 app.hidden = false;
13216 }
13217 if (client.keeping) {
13218 app.keeping = true;
13219 }
13220 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013221 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013222 }
13223 if (adjType != null) {
13224 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013225 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13226 .REASON_SERVICE_IN_USE;
13227 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013228 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013229 app.adjTarget = s.name;
13230 }
13231 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13232 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13233 schedGroup = Process.THREAD_GROUP_DEFAULT;
13234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013235 }
13236 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013237 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13238 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013239 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013240 (a.visible || a.state == ActivityState.RESUMED
13241 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013242 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013243 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13244 schedGroup = Process.THREAD_GROUP_DEFAULT;
13245 }
13246 app.hidden = false;
13247 app.adjType = "service";
13248 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13249 .REASON_SERVICE_IN_USE;
13250 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013251 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013252 app.adjTarget = s.name;
13253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013255 }
13256 }
13257 }
13258 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013259
Dianne Hackborn287952c2010-09-22 22:34:31 -070013260 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013261 // would like to avoid killing it unless it would prevent the current
13262 // application from running. By default we put the process in
13263 // with the rest of the background processes; as we scan through
13264 // its services we may bump it up from there.
13265 if (adj > hiddenAdj) {
13266 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013267 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013268 app.adjType = "bg-services";
13269 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013270 }
13271
Dianne Hackborn7d608422011-08-07 16:24:18 -070013272 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013273 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013274 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013275 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013276 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013277 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013278 if (cpr.clients.size() != 0) {
13279 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013280 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013281 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013282 if (client == app) {
13283 // Being our own client is not interesting.
13284 continue;
13285 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013286 int myHiddenAdj = hiddenAdj;
13287 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013288 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013289 myHiddenAdj = client.hiddenAdj;
13290 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013291 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013292 }
13293 }
13294 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013295 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013296 if (adj > clientAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013297 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013298 app.adjType = "bg-ui-provider";
13299 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013300 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13301 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013302 app.adjType = "provider";
13303 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013304 if (!client.hidden) {
13305 app.hidden = false;
13306 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013307 if (client.keeping) {
13308 app.keeping = true;
13309 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013310 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13311 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013312 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013313 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013314 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013315 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013316 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13317 schedGroup = Process.THREAD_GROUP_DEFAULT;
13318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013319 }
13320 }
13321 // If the provider has external (non-framework) process
13322 // dependencies, ensure that its adjustment is at least
13323 // FOREGROUND_APP_ADJ.
13324 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013325 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13326 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013327 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013328 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013329 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013330 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013331 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013332 }
13333 }
13334 }
13335 }
13336
13337 app.curRawAdj = adj;
13338
Joe Onorato8a9b2202010-02-26 18:56:32 -080013339 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013340 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13341 if (adj > app.maxAdj) {
13342 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013343 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013344 schedGroup = Process.THREAD_GROUP_DEFAULT;
13345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013346 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013347 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013348 app.keeping = true;
13349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013350
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013351 if (app.hasAboveClient) {
13352 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13353 // then we need to drop its adjustment to be lower than the service's
13354 // in order to honor the request. We want to drop it by one adjustment
13355 // level... but there is special meaning applied to various levels so
13356 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013357 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013358 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013359 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13360 adj = ProcessList.VISIBLE_APP_ADJ;
13361 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13362 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13363 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13364 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13365 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013366 adj++;
13367 }
13368 }
13369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013370 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013371 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013372
13373 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013374 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13375 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013376 }
13377
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013378 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013379 }
13380
13381 /**
13382 * Ask a given process to GC right now.
13383 */
13384 final void performAppGcLocked(ProcessRecord app) {
13385 try {
13386 app.lastRequestedGc = SystemClock.uptimeMillis();
13387 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013388 if (app.reportLowMemory) {
13389 app.reportLowMemory = false;
13390 app.thread.scheduleLowMemory();
13391 } else {
13392 app.thread.processInBackground();
13393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013394 }
13395 } catch (Exception e) {
13396 // whatever.
13397 }
13398 }
13399
13400 /**
13401 * Returns true if things are idle enough to perform GCs.
13402 */
Josh Bartel7f208742010-02-25 11:01:44 -060013403 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013404 return mParallelBroadcasts.size() == 0
13405 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013406 && (mSleeping || (mMainStack.mResumedActivity != null &&
13407 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013408 }
13409
13410 /**
13411 * Perform GCs on all processes that are waiting for it, but only
13412 * if things are idle.
13413 */
13414 final void performAppGcsLocked() {
13415 final int N = mProcessesToGc.size();
13416 if (N <= 0) {
13417 return;
13418 }
Josh Bartel7f208742010-02-25 11:01:44 -060013419 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013420 while (mProcessesToGc.size() > 0) {
13421 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013422 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013423 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13424 <= SystemClock.uptimeMillis()) {
13425 // To avoid spamming the system, we will GC processes one
13426 // at a time, waiting a few seconds between each.
13427 performAppGcLocked(proc);
13428 scheduleAppGcsLocked();
13429 return;
13430 } else {
13431 // It hasn't been long enough since we last GCed this
13432 // process... put it in the list to wait for its time.
13433 addProcessToGcListLocked(proc);
13434 break;
13435 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013436 }
13437 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013438
13439 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013440 }
13441 }
13442
13443 /**
13444 * If all looks good, perform GCs on all processes waiting for them.
13445 */
13446 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013447 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013448 performAppGcsLocked();
13449 return;
13450 }
13451 // Still not idle, wait some more.
13452 scheduleAppGcsLocked();
13453 }
13454
13455 /**
13456 * Schedule the execution of all pending app GCs.
13457 */
13458 final void scheduleAppGcsLocked() {
13459 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013460
13461 if (mProcessesToGc.size() > 0) {
13462 // Schedule a GC for the time to the next process.
13463 ProcessRecord proc = mProcessesToGc.get(0);
13464 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13465
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013466 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013467 long now = SystemClock.uptimeMillis();
13468 if (when < (now+GC_TIMEOUT)) {
13469 when = now + GC_TIMEOUT;
13470 }
13471 mHandler.sendMessageAtTime(msg, when);
13472 }
13473 }
13474
13475 /**
13476 * Add a process to the array of processes waiting to be GCed. Keeps the
13477 * list in sorted order by the last GC time. The process can't already be
13478 * on the list.
13479 */
13480 final void addProcessToGcListLocked(ProcessRecord proc) {
13481 boolean added = false;
13482 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13483 if (mProcessesToGc.get(i).lastRequestedGc <
13484 proc.lastRequestedGc) {
13485 added = true;
13486 mProcessesToGc.add(i+1, proc);
13487 break;
13488 }
13489 }
13490 if (!added) {
13491 mProcessesToGc.add(0, proc);
13492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013493 }
13494
13495 /**
13496 * Set up to ask a process to GC itself. This will either do it
13497 * immediately, or put it on the list of processes to gc the next
13498 * time things are idle.
13499 */
13500 final void scheduleAppGcLocked(ProcessRecord app) {
13501 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013502 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013503 return;
13504 }
13505 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013506 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013507 scheduleAppGcsLocked();
13508 }
13509 }
13510
Dianne Hackborn287952c2010-09-22 22:34:31 -070013511 final void checkExcessivePowerUsageLocked(boolean doKills) {
13512 updateCpuStatsNow();
13513
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013514 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013515 boolean doWakeKills = doKills;
13516 boolean doCpuKills = doKills;
13517 if (mLastPowerCheckRealtime == 0) {
13518 doWakeKills = false;
13519 }
13520 if (mLastPowerCheckUptime == 0) {
13521 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013522 }
13523 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013524 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013525 }
13526 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013527 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13528 final long curUptime = SystemClock.uptimeMillis();
13529 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13530 mLastPowerCheckRealtime = curRealtime;
13531 mLastPowerCheckUptime = curUptime;
13532 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13533 doWakeKills = false;
13534 }
13535 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13536 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013537 }
13538 int i = mLruProcesses.size();
13539 while (i > 0) {
13540 i--;
13541 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013542 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013543 long wtime;
13544 synchronized (stats) {
13545 wtime = stats.getProcessWakeTime(app.info.uid,
13546 app.pid, curRealtime);
13547 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013548 long wtimeUsed = wtime - app.lastWakeTime;
13549 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13550 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013551 StringBuilder sb = new StringBuilder(128);
13552 sb.append("Wake for ");
13553 app.toShortString(sb);
13554 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013555 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013556 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013557 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013558 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013559 sb.append((wtimeUsed*100)/realtimeSince);
13560 sb.append("%)");
13561 Slog.i(TAG, sb.toString());
13562 sb.setLength(0);
13563 sb.append("CPU for ");
13564 app.toShortString(sb);
13565 sb.append(": over ");
13566 TimeUtils.formatDuration(uptimeSince, sb);
13567 sb.append(" used ");
13568 TimeUtils.formatDuration(cputimeUsed, sb);
13569 sb.append(" (");
13570 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013571 sb.append("%)");
13572 Slog.i(TAG, sb.toString());
13573 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013574 // If a process has held a wake lock for more
13575 // than 50% of the time during this period,
13576 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013577 if (doWakeKills && realtimeSince > 0
13578 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13579 synchronized (stats) {
13580 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13581 realtimeSince, wtimeUsed);
13582 }
13583 Slog.w(TAG, "Excessive wake lock in " + app.processName
13584 + " (pid " + app.pid + "): held " + wtimeUsed
13585 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013586 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13587 app.processName, app.setAdj, "excessive wake lock");
13588 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013589 } else if (doCpuKills && uptimeSince > 0
13590 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13591 synchronized (stats) {
13592 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13593 uptimeSince, cputimeUsed);
13594 }
13595 Slog.w(TAG, "Excessive CPU in " + app.processName
13596 + " (pid " + app.pid + "): used " + cputimeUsed
13597 + " during " + uptimeSince);
13598 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13599 app.processName, app.setAdj, "excessive cpu");
13600 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013601 } else {
13602 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013603 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013604 }
13605 }
13606 }
13607 }
13608
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013609 private final boolean updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013610 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013611 app.hiddenAdj = hiddenAdj;
13612
13613 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013614 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013615 }
13616
Dianne Hackborn287952c2010-09-22 22:34:31 -070013617 final boolean wasKeeping = app.keeping;
13618
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013619 boolean success = true;
13620
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013621 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013622
Jeff Brown10e89712011-07-08 18:52:57 -070013623 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070013624 if (false) {
13625 // Removing for now. Forcing GCs is not so useful anymore
13626 // with Dalvik, and the new memory level hint facility is
13627 // better for what we need to do these days.
13628 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13629 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13630 // If this app is transitioning from foreground to
13631 // non-foreground, have it do a gc.
13632 scheduleAppGcLocked(app);
13633 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13634 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13635 // Likewise do a gc when an app is moving in to the
13636 // background (such as a service stopping).
13637 scheduleAppGcLocked(app);
13638 }
Jeff Brown10e89712011-07-08 18:52:57 -070013639 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013640
Jeff Brown10e89712011-07-08 18:52:57 -070013641 if (wasKeeping && !app.keeping) {
13642 // This app is no longer something we want to keep. Note
13643 // its current wake lock time to later know to kill it if
13644 // it is not behaving well.
13645 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13646 synchronized (stats) {
13647 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13648 app.pid, SystemClock.elapsedRealtime());
13649 }
13650 app.lastCpuTime = app.curCpuTime;
13651 }
13652
13653 app.setRawAdj = app.curRawAdj;
13654 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013655 if (app.curAdj != app.setAdj) {
13656 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013657 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13658 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013659 " oom adj to " + app.curAdj + " because " + app.adjType);
13660 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013661 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013662 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013663 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013664 }
13665 }
13666 if (app.setSchedGroup != app.curSchedGroup) {
13667 app.setSchedGroup = app.curSchedGroup;
13668 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13669 "Setting process group of " + app.processName
13670 + " to " + app.curSchedGroup);
13671 if (app.waitingToKill != null &&
13672 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13673 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13674 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13675 app.processName, app.setAdj, app.waitingToKill);
13676 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013677 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013678 } else {
13679 if (true) {
13680 long oldId = Binder.clearCallingIdentity();
13681 try {
13682 Process.setProcessGroup(app.pid, app.curSchedGroup);
13683 } catch (Exception e) {
13684 Slog.w(TAG, "Failed setting process group of " + app.pid
13685 + " to " + app.curSchedGroup);
13686 e.printStackTrace();
13687 } finally {
13688 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013689 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013690 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013691 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013692 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013693 app.thread.setSchedulingGroup(app.curSchedGroup);
13694 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013695 }
13696 }
13697 }
13698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013699 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013700 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013701 }
13702
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013703 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013704 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013705 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013706 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013707 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013708 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013709 }
13710 }
13711 return resumedActivity;
13712 }
13713
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013714 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013715 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013716 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13717 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013718 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13719 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013720
13721 mAdjSeq++;
13722
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013723 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013724 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13725 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013726 if (nowHidden != wasHidden) {
13727 // Changed to/from hidden state, so apps after it in the LRU
13728 // list may also be changed.
13729 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013730 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013731 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013732 }
13733
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013734 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013735 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013736 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13737
13738 if (false) {
13739 RuntimeException e = new RuntimeException();
13740 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013741 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013742 }
13743
13744 mAdjSeq++;
13745
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013746 // Let's determine how many processes we have running vs.
13747 // how many slots we have for background processes; we may want
13748 // to put multiple processes in a slot of there are enough of
13749 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013750 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013751 int factor = (mLruProcesses.size()-4)/numSlots;
13752 if (factor < 1) factor = 1;
13753 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013754 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013755
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013756 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013757 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013758 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013759 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013760 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013761 while (i > 0) {
13762 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013763 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013764 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013765 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013766 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013767 && app.curAdj == curHiddenAdj) {
13768 step++;
13769 if (step >= factor) {
13770 step = 0;
13771 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013772 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013773 }
13774 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013775 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013776 numHidden++;
13777 if (numHidden > mProcessLimit) {
13778 Slog.i(TAG, "No longer want " + app.processName
13779 + " (pid " + app.pid + "): hidden #" + numHidden);
13780 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13781 app.processName, app.setAdj, "too many background");
13782 app.killedBackground = true;
13783 Process.killProcessQuiet(app.pid);
13784 } else {
13785 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013786 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013787 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013788 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013790 }
13791 }
13792
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013793 // Now determine the memory trimming level of background processes.
13794 // Unfortunately we need to start at the back of the list to do this
13795 // properly. We only do this if the number of background apps we
13796 // are managing to keep around is less than half the maximum we desire;
13797 // if we are keeping a good number around, we'll let them use whatever
13798 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013799 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013800 final int N = mLruProcesses.size();
13801 factor = numBg/3;
13802 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013803 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013804 for (i=0; i<N; i++) {
13805 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013806 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013807 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13808 try {
13809 app.thread.scheduleTrimMemory(curLevel);
13810 } catch (RemoteException e) {
13811 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013812 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013813 // For these apps we will also finish their activities
13814 // to help them free memory.
13815 mMainStack.destroyActivitiesLocked(app, false);
13816 }
13817 }
13818 app.trimMemoryLevel = curLevel;
13819 step++;
13820 if (step >= factor) {
13821 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013822 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13823 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013824 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013825 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13826 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013827 break;
13828 }
13829 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013830 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013831 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013832 && app.thread != null) {
13833 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013834 app.thread.scheduleTrimMemory(
13835 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013836 } catch (RemoteException e) {
13837 }
13838 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013839 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013840 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013841 && app.pendingUiClean) {
13842 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13843 && app.thread != null) {
13844 try {
13845 app.thread.scheduleTrimMemory(
13846 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13847 } catch (RemoteException e) {
13848 }
13849 }
13850 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13851 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013852 } else {
13853 app.trimMemoryLevel = 0;
13854 }
13855 }
13856 } else {
13857 final int N = mLruProcesses.size();
13858 for (i=0; i<N; i++) {
13859 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013860 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013861 && app.pendingUiClean) {
13862 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13863 && app.thread != null) {
13864 try {
13865 app.thread.scheduleTrimMemory(
13866 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13867 } catch (RemoteException e) {
13868 }
13869 }
13870 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13871 app.pendingUiClean = false;
13872 } else {
13873 app.trimMemoryLevel = 0;
13874 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013875 }
13876 }
13877
13878 if (mAlwaysFinishActivities) {
13879 mMainStack.destroyActivitiesLocked(null, false);
13880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013881 }
13882
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013883 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013884 synchronized (this) {
13885 int i;
13886
13887 // First remove any unused application processes whose package
13888 // has been removed.
13889 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13890 final ProcessRecord app = mRemovedProcesses.get(i);
13891 if (app.activities.size() == 0
13892 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013893 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013894 TAG, "Exiting empty application process "
13895 + app.processName + " ("
13896 + (app.thread != null ? app.thread.asBinder() : null)
13897 + ")\n");
13898 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013899 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13900 app.processName, app.setAdj, "empty");
13901 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013902 } else {
13903 try {
13904 app.thread.scheduleExit();
13905 } catch (Exception e) {
13906 // Ignore exceptions.
13907 }
13908 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013909 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013910 mRemovedProcesses.remove(i);
13911
13912 if (app.persistent) {
13913 if (app.persistent) {
13914 addAppLocked(app.info);
13915 }
13916 }
13917 }
13918 }
13919
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013920 // Now update the oom adj for all processes.
13921 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013922 }
13923 }
13924
13925 /** This method sends the specified signal to each of the persistent apps */
13926 public void signalPersistentProcesses(int sig) throws RemoteException {
13927 if (sig != Process.SIGNAL_USR1) {
13928 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13929 }
13930
13931 synchronized (this) {
13932 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13933 != PackageManager.PERMISSION_GRANTED) {
13934 throw new SecurityException("Requires permission "
13935 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13936 }
13937
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013938 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13939 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013940 if (r.thread != null && r.persistent) {
13941 Process.sendSignal(r.pid, sig);
13942 }
13943 }
13944 }
13945 }
13946
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013947 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13948 if (proc == null || proc == mProfileProc) {
13949 proc = mProfileProc;
13950 path = mProfileFile;
13951 profileType = mProfileType;
13952 clearProfilerLocked();
13953 }
13954 if (proc == null) {
13955 return;
13956 }
13957 try {
13958 proc.thread.profilerControl(false, path, null, profileType);
13959 } catch (RemoteException e) {
13960 throw new IllegalStateException("Process disappeared");
13961 }
13962 }
13963
13964 private void clearProfilerLocked() {
13965 if (mProfileFd != null) {
13966 try {
13967 mProfileFd.close();
13968 } catch (IOException e) {
13969 }
13970 }
13971 mProfileApp = null;
13972 mProfileProc = null;
13973 mProfileFile = null;
13974 mProfileType = 0;
13975 mAutoStopProfiler = false;
13976 }
13977
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013978 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013979 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013980
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013981 try {
13982 synchronized (this) {
13983 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13984 // its own permission.
13985 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13986 != PackageManager.PERMISSION_GRANTED) {
13987 throw new SecurityException("Requires permission "
13988 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013989 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013990
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013991 if (start && fd == null) {
13992 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013993 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013994
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013995 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013996 if (process != null) {
13997 try {
13998 int pid = Integer.parseInt(process);
13999 synchronized (mPidsSelfLocked) {
14000 proc = mPidsSelfLocked.get(pid);
14001 }
14002 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014003 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014004
14005 if (proc == null) {
14006 HashMap<String, SparseArray<ProcessRecord>> all
14007 = mProcessNames.getMap();
14008 SparseArray<ProcessRecord> procs = all.get(process);
14009 if (procs != null && procs.size() > 0) {
14010 proc = procs.valueAt(0);
14011 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014012 }
14013 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014014
14015 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014016 throw new IllegalArgumentException("Unknown process: " + process);
14017 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014018
14019 if (start) {
14020 stopProfilerLocked(null, null, 0);
14021 setProfileApp(proc.info, proc.processName, path, fd, false);
14022 mProfileProc = proc;
14023 mProfileType = profileType;
14024 try {
14025 fd = fd.dup();
14026 } catch (IOException e) {
14027 fd = null;
14028 }
14029 proc.thread.profilerControl(start, path, fd, profileType);
14030 fd = null;
14031 mProfileFd = null;
14032 } else {
14033 stopProfilerLocked(proc, path, profileType);
14034 if (fd != null) {
14035 try {
14036 fd.close();
14037 } catch (IOException e) {
14038 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014039 }
14040 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014041
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014042 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014043 }
14044 } catch (RemoteException e) {
14045 throw new IllegalStateException("Process disappeared");
14046 } finally {
14047 if (fd != null) {
14048 try {
14049 fd.close();
14050 } catch (IOException e) {
14051 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014052 }
14053 }
14054 }
Andy McFadden824c5102010-07-09 16:26:57 -070014055
14056 public boolean dumpHeap(String process, boolean managed,
14057 String path, ParcelFileDescriptor fd) throws RemoteException {
14058
14059 try {
14060 synchronized (this) {
14061 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14062 // its own permission (same as profileControl).
14063 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14064 != PackageManager.PERMISSION_GRANTED) {
14065 throw new SecurityException("Requires permission "
14066 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14067 }
14068
14069 if (fd == null) {
14070 throw new IllegalArgumentException("null fd");
14071 }
14072
14073 ProcessRecord proc = null;
14074 try {
14075 int pid = Integer.parseInt(process);
14076 synchronized (mPidsSelfLocked) {
14077 proc = mPidsSelfLocked.get(pid);
14078 }
14079 } catch (NumberFormatException e) {
14080 }
14081
14082 if (proc == null) {
14083 HashMap<String, SparseArray<ProcessRecord>> all
14084 = mProcessNames.getMap();
14085 SparseArray<ProcessRecord> procs = all.get(process);
14086 if (procs != null && procs.size() > 0) {
14087 proc = procs.valueAt(0);
14088 }
14089 }
14090
14091 if (proc == null || proc.thread == null) {
14092 throw new IllegalArgumentException("Unknown process: " + process);
14093 }
14094
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014095 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14096 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014097 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14098 throw new SecurityException("Process not debuggable: " + proc);
14099 }
14100 }
14101
14102 proc.thread.dumpHeap(managed, path, fd);
14103 fd = null;
14104 return true;
14105 }
14106 } catch (RemoteException e) {
14107 throw new IllegalStateException("Process disappeared");
14108 } finally {
14109 if (fd != null) {
14110 try {
14111 fd.close();
14112 } catch (IOException e) {
14113 }
14114 }
14115 }
14116 }
14117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014118 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14119 public void monitor() {
14120 synchronized (this) { }
14121 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014122
14123 public void onCoreSettingsChange(Bundle settings) {
14124 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14125 ProcessRecord processRecord = mLruProcesses.get(i);
14126 try {
14127 if (processRecord.thread != null) {
14128 processRecord.thread.setCoreSettings(settings);
14129 }
14130 } catch (RemoteException re) {
14131 /* ignore */
14132 }
14133 }
14134 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014135
14136 // Multi-user methods
14137
14138 public boolean switchUser(int userid) {
14139 // TODO
14140 return true;
14141 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014142}