blob: ed960d6d219f838171f4664dd9feb472cdab472c [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Dianne Hackborn905577f2011-09-07 18:31:28 -0700109import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800111import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.util.PrintWriterPrinter;
113import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700114import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Gravity;
116import android.view.LayoutInflater;
117import android.view.View;
118import android.view.WindowManager;
119import android.view.WindowManagerPolicy;
120
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700121import java.io.BufferedInputStream;
122import java.io.BufferedOutputStream;
123import java.io.DataInputStream;
124import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import java.io.File;
126import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700127import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700129import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200130import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800131import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132import java.io.PrintWriter;
133import java.lang.IllegalStateException;
134import java.lang.ref.WeakReference;
135import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700136import java.util.Collections;
137import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138import java.util.HashMap;
139import java.util.HashSet;
140import java.util.Iterator;
141import java.util.List;
142import java.util.Locale;
143import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700144import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700145import java.util.concurrent.atomic.AtomicBoolean;
146import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700148public final class ActivityManagerService extends ActivityManagerNative
149 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 static final String TAG = "ActivityManager";
151 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400152 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 static final boolean DEBUG_SWITCH = localLOGV || false;
154 static final boolean DEBUG_TASKS = localLOGV || false;
155 static final boolean DEBUG_PAUSE = localLOGV || false;
156 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
157 static final boolean DEBUG_TRANSITION = localLOGV || false;
158 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700159 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700161 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_VISBILITY = localLOGV || false;
163 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700164 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800165 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700167 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700168 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700169 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700170 static final boolean DEBUG_POWER = localLOGV || false;
171 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 static final boolean VALIDATE_TOKENS = false;
173 static final boolean SHOW_ACTIVITY_START_TIME = true;
174
175 // Control over CPU and battery monitoring.
176 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
177 static final boolean MONITOR_CPU_USAGE = true;
178 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
179 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
180 static final boolean MONITOR_THREAD_CPU_USAGE = false;
181
Dianne Hackborn1655be42009-05-08 14:29:01 -0700182 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700183 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700184
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800185 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 // Maximum number of recent tasks that we can remember.
188 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700189
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700190 // Amount of time after a call to stopAppSwitches() during which we will
191 // prevent further untrusted switches from happening.
192 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193
194 // How long we wait for a launched process to attach to the activity manager
195 // before we decide it's never going to come up for real.
196 static final int PROC_START_TIMEOUT = 10*1000;
197
Jeff Brown3f9dd282011-07-08 20:02:19 -0700198 // How long we wait for a launched process to attach to the activity manager
199 // before we decide it's never going to come up for real, when the process was
200 // started with a wrapper for instrumentation (such as Valgrind) because it
201 // could take much longer than usual.
202 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 // How long to wait after going idle before forcing apps to GC.
205 static final int GC_TIMEOUT = 5*1000;
206
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700207 // The minimum amount of time between successive GC requests for a process.
208 static final int GC_MIN_INTERVAL = 60*1000;
209
Dianne Hackborn287952c2010-09-22 22:34:31 -0700210 // The rate at which we check for apps using excessive power -- 15 mins.
211 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
212
213 // The minimum sample duration we will allow before deciding we have
214 // enough data on wake locks to start killing things.
215 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
216
217 // The minimum sample duration we will allow before deciding we have
218 // enough data on CPU usage to start killing things.
219 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 // How long we allow a receiver to run before giving up on it.
222 static final int BROADCAST_TIMEOUT = 10*1000;
223
224 // How long we wait for a service to finish executing.
225 static final int SERVICE_TIMEOUT = 20*1000;
226
227 // How long a service needs to be running until restarting its process
228 // is no longer considered to be a relaunch of the service.
229 static final int SERVICE_RESTART_DURATION = 5*1000;
230
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700231 // How long a service needs to be running until it will start back at
232 // SERVICE_RESTART_DURATION after being killed.
233 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
234
235 // Multiplying factor to increase restart duration time by, for each time
236 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
237 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
238
239 // The minimum amount of time between restarting services that we allow.
240 // That is, when multiple services are restarting, we won't allow each
241 // to restart less than this amount of time from the last one.
242 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 // Maximum amount of time for there to be no activity on a service before
245 // we consider it non-essential and allow its process to go on the
246 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700247 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248
249 // How long we wait until we timeout on key dispatching.
250 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 // How long we wait until we timeout on key dispatching during instrumentation.
253 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
254
Dan Egnor42471dd2010-01-07 17:25:22 -0800255 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256
257 static final String[] EMPTY_STRING_ARRAY = new String[0];
258
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700259 public ActivityStack mMainStack;
260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700262 * Description of a request to start a new activity, which has been held
263 * due to app switches being disabled.
264 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700265 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700266 ActivityRecord r;
267 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700268 Uri[] grantedUriPermissions;
269 int grantedMode;
270 boolean onlyIfNeeded;
271 }
272
273 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
274 = new ArrayList<PendingActivityLaunch>();
275
276 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 * List of all active broadcasts that are to be executed immediately
278 * (without waiting for another broadcast to finish). Currently this only
279 * contains broadcasts to registered receivers, to avoid spinning up
280 * a bunch of processes to execute IntentReceiver components.
281 */
282 final ArrayList<BroadcastRecord> mParallelBroadcasts
283 = new ArrayList<BroadcastRecord>();
284
285 /**
286 * List of all active broadcasts that are to be executed one at a time.
287 * The object at the top of the list is the currently activity broadcasts;
288 * those after it are waiting for the top to finish..
289 */
290 final ArrayList<BroadcastRecord> mOrderedBroadcasts
291 = new ArrayList<BroadcastRecord>();
292
293 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800294 * Historical data of past broadcasts, for debugging.
295 */
296 static final int MAX_BROADCAST_HISTORY = 100;
297 final BroadcastRecord[] mBroadcastHistory
298 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
299
300 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 * Set when we current have a BROADCAST_INTENT_MSG in flight.
302 */
303 boolean mBroadcastsScheduled = false;
304
305 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 * Activity we have told the window manager to have key focus.
307 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700308 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700309 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 * List of intents that were used to start the most recent tasks.
311 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700312 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313
314 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700315 * Process management.
316 */
317 final ProcessList mProcessList = new ProcessList();
318
319 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 * All of the applications we currently have running organized by name.
321 * The keys are strings of the application package name (as
322 * returned by the package manager), and the keys are ApplicationRecord
323 * objects.
324 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700325 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326
327 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700328 * The currently running heavy-weight process, if any.
329 */
330 ProcessRecord mHeavyWeightProcess = null;
331
332 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 * The last time that various processes have crashed.
334 */
335 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
336
337 /**
338 * Set of applications that we consider to be bad, and will reject
339 * incoming broadcasts from (which the user has no control over).
340 * Processes are added to this set when they have crashed twice within
341 * a minimum amount of time; they are removed from it when they are
342 * later restarted (hopefully due to some user action). The value is the
343 * time it was added to the list.
344 */
345 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
346
347 /**
348 * All of the processes we currently have running organized by pid.
349 * The keys are the pid running the application.
350 *
351 * <p>NOTE: This object is protected by its own lock, NOT the global
352 * activity manager lock!
353 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700354 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355
356 /**
357 * All of the processes that have been forced to be foreground. The key
358 * is the pid of the caller who requested it (we hold a death
359 * link on it).
360 */
361 abstract class ForegroundToken implements IBinder.DeathRecipient {
362 int pid;
363 IBinder token;
364 }
365 final SparseArray<ForegroundToken> mForegroundProcesses
366 = new SparseArray<ForegroundToken>();
367
368 /**
369 * List of records for processes that someone had tried to start before the
370 * system was ready. We don't start them at that point, but ensure they
371 * are started by the time booting is complete.
372 */
373 final ArrayList<ProcessRecord> mProcessesOnHold
374 = new ArrayList<ProcessRecord>();
375
376 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 * List of persistent applications that are in the process
378 * of being started.
379 */
380 final ArrayList<ProcessRecord> mPersistentStartingProcesses
381 = new ArrayList<ProcessRecord>();
382
383 /**
384 * Processes that are being forcibly torn down.
385 */
386 final ArrayList<ProcessRecord> mRemovedProcesses
387 = new ArrayList<ProcessRecord>();
388
389 /**
390 * List of running applications, sorted by recent usage.
391 * The first entry in the list is the least recently used.
392 * It contains ApplicationRecord objects. This list does NOT include
393 * any persistent application records (since we never want to exit them).
394 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800395 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 = new ArrayList<ProcessRecord>();
397
398 /**
399 * List of processes that should gc as soon as things are idle.
400 */
401 final ArrayList<ProcessRecord> mProcessesToGc
402 = new ArrayList<ProcessRecord>();
403
404 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800405 * This is the process holding what we currently consider to be
406 * the "home" activity.
407 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700408 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800409
410 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400411 * Packages that the user has asked to have run in screen size
412 * compatibility mode instead of filling the screen.
413 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700414 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400415
416 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 * Set of PendingResultRecord objects that are currently active.
418 */
419 final HashSet mPendingResultRecords = new HashSet();
420
421 /**
422 * Set of IntentSenderRecord objects that are currently active.
423 */
424 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
425 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
426
427 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800428 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700429 * already logged DropBox entries for. Guarded by itself. If
430 * something (rogue user app) forces this over
431 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
432 */
433 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
434 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
435
436 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700437 * Strict Mode background batched logging state.
438 *
439 * The string buffer is guarded by itself, and its lock is also
440 * used to determine if another batched write is already
441 * in-flight.
442 */
443 private final StringBuilder mStrictModeBuffer = new StringBuilder();
444
445 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700446 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
447 */
448 private boolean mPendingBroadcastTimeoutMessage;
449
450 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 * Intent broadcast that we have tried to start, but are
452 * waiting for its application's process to be created. We only
453 * need one (instead of a list) because we always process broadcasts
454 * one at a time, so no others can be started while waiting for this
455 * one.
456 */
457 BroadcastRecord mPendingBroadcast = null;
458
459 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700460 * The receiver index that is pending, to restart the broadcast if needed.
461 */
462 int mPendingBroadcastRecvIndex;
463
464 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 * Keeps track of all IIntentReceivers that have been registered for
466 * broadcasts. Hash keys are the receiver IBinder, hash value is
467 * a ReceiverList.
468 */
469 final HashMap mRegisteredReceivers = new HashMap();
470
471 /**
472 * Resolver for broadcast intents to registered receivers.
473 * Holds BroadcastFilter (subclass of IntentFilter).
474 */
475 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
476 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
477 @Override
478 protected boolean allowFilterResult(
479 BroadcastFilter filter, List<BroadcastFilter> dest) {
480 IBinder target = filter.receiverList.receiver.asBinder();
481 for (int i=dest.size()-1; i>=0; i--) {
482 if (dest.get(i).receiverList.receiver.asBinder() == target) {
483 return false;
484 }
485 }
486 return true;
487 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700488
489 @Override
490 protected String packageForFilter(BroadcastFilter filter) {
491 return filter.packageName;
492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 };
494
495 /**
496 * State of all active sticky broadcasts. Keys are the action of the
497 * sticky Intent, values are an ArrayList of all broadcasted intents with
498 * that action (which should usually be one).
499 */
500 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
501 new HashMap<String, ArrayList<Intent>>();
502
503 /**
504 * All currently running services.
505 */
506 final HashMap<ComponentName, ServiceRecord> mServices =
507 new HashMap<ComponentName, ServiceRecord>();
508
509 /**
510 * All currently running services indexed by the Intent used to start them.
511 */
512 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
513 new HashMap<Intent.FilterComparison, ServiceRecord>();
514
515 /**
516 * All currently bound service connections. Keys are the IBinder of
517 * the client's IServiceConnection.
518 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700519 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
520 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521
522 /**
523 * List of services that we have been asked to start,
524 * but haven't yet been able to. It is used to hold start requests
525 * while waiting for their corresponding application thread to get
526 * going.
527 */
528 final ArrayList<ServiceRecord> mPendingServices
529 = new ArrayList<ServiceRecord>();
530
531 /**
532 * List of services that are scheduled to restart following a crash.
533 */
534 final ArrayList<ServiceRecord> mRestartingServices
535 = new ArrayList<ServiceRecord>();
536
537 /**
538 * List of services that are in the process of being stopped.
539 */
540 final ArrayList<ServiceRecord> mStoppingServices
541 = new ArrayList<ServiceRecord>();
542
543 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700544 * Backup/restore process management
545 */
546 String mBackupAppName = null;
547 BackupRecord mBackupTarget = null;
548
549 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 * List of PendingThumbnailsRecord objects of clients who are still
551 * waiting to receive all of the thumbnails for a task.
552 */
553 final ArrayList mPendingThumbnails = new ArrayList();
554
555 /**
556 * List of HistoryRecord objects that have been finished and must
557 * still report back to a pending thumbnail receiver.
558 */
559 final ArrayList mCancelledThumbnails = new ArrayList();
560
561 /**
562 * All of the currently running global content providers. Keys are a
563 * string containing the provider name and values are a
564 * ContentProviderRecord object containing the data about it. Note
565 * that a single provider may be published under multiple names, so
566 * there may be multiple entries here for a single one in mProvidersByClass.
567 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700568 final HashMap<String, ContentProviderRecord> mProvidersByName
569 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570
571 /**
572 * All of the currently running global content providers. Keys are a
573 * string containing the provider's implementation class and values are a
574 * ContentProviderRecord object containing the data about it.
575 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700576 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
577 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578
579 /**
580 * List of content providers who have clients waiting for them. The
581 * application is currently being launched and the provider will be
582 * removed from this list once it is published.
583 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700584 final ArrayList<ContentProviderRecord> mLaunchingProviders
585 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586
587 /**
588 * Global set of specific Uri permissions that have been granted.
589 */
590 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
591 = new SparseArray<HashMap<Uri, UriPermission>>();
592
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800593 CoreSettingsObserver mCoreSettingsObserver;
594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 /**
596 * Thread-local storage used to carry caller permissions over through
597 * indirect content-provider access.
598 * @see #ActivityManagerService.openContentUri()
599 */
600 private class Identity {
601 public int pid;
602 public int uid;
603
604 Identity(int _pid, int _uid) {
605 pid = _pid;
606 uid = _uid;
607 }
608 }
609 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
610
611 /**
612 * All information we have collected about the runtime performance of
613 * any user id that can impact battery performance.
614 */
615 final BatteryStatsService mBatteryStatsService;
616
617 /**
618 * information about component usage
619 */
620 final UsageStatsService mUsageStatsService;
621
622 /**
623 * Current configuration information. HistoryRecord objects are given
624 * a reference to this object to indicate which configuration they are
625 * currently running in, so this object must be kept immutable.
626 */
627 Configuration mConfiguration = new Configuration();
628
629 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800630 * Current sequencing integer of the configuration, for skipping old
631 * configurations.
632 */
633 int mConfigurationSeq = 0;
634
635 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700636 * Hardware-reported OpenGLES version.
637 */
638 final int GL_ES_VERSION;
639
640 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 * List of initialization arguments to pass to all processes when binding applications to them.
642 * For example, references to the commonly used services.
643 */
644 HashMap<String, IBinder> mAppBindArgs;
645
646 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700647 * Temporary to avoid allocations. Protected by main lock.
648 */
649 final StringBuilder mStringBuilder = new StringBuilder(256);
650
651 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 * Used to control how we initialize the service.
653 */
654 boolean mStartRunning = false;
655 ComponentName mTopComponent;
656 String mTopAction;
657 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700658 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 boolean mSystemReady = false;
660 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700661 boolean mWaitingUpdate = false;
662 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700663 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700664 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665
666 Context mContext;
667
668 int mFactoryTest;
669
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700670 boolean mCheckedForSetup;
671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700673 * The time at which we will allow normal application switches again,
674 * after a call to {@link #stopAppSwitches()}.
675 */
676 long mAppSwitchesAllowedTime;
677
678 /**
679 * This is set to true after the first switch after mAppSwitchesAllowedTime
680 * is set; any switches after that will clear the time.
681 */
682 boolean mDidAppSwitch;
683
684 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700685 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700686 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700687 long mLastPowerCheckRealtime;
688
689 /**
690 * Last time (in uptime) at which we checked for power usage.
691 */
692 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700693
694 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 * Set while we are wanting to sleep, to prevent any
696 * activities from being started/resumed.
697 */
698 boolean mSleeping = false;
699
700 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700701 * Set if we are shutting down the system, similar to sleeping.
702 */
703 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704
705 /**
706 * Task identifier that activities are currently being started
707 * in. Incremented each time a new task is created.
708 * todo: Replace this with a TokenSpace class that generates non-repeating
709 * integers that won't wrap.
710 */
711 int mCurTask = 1;
712
713 /**
714 * Current sequence id for oom_adj computation traversal.
715 */
716 int mAdjSeq = 0;
717
718 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700719 * Current sequence id for process LRU updating.
720 */
721 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722
723 /**
724 * System monitoring: number of processes that died since the last
725 * N procs were started.
726 */
727 int[] mProcDeaths = new int[20];
728
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700729 /**
730 * This is set if we had to do a delayed dexopt of an app before launching
731 * it, to increasing the ANR timeouts in that case.
732 */
733 boolean mDidDexOpt;
734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 String mDebugApp = null;
736 boolean mWaitForDebugger = false;
737 boolean mDebugTransient = false;
738 String mOrigDebugApp = null;
739 boolean mOrigWaitForDebugger = false;
740 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700741 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700742 String mProfileApp = null;
743 ProcessRecord mProfileProc = null;
744 String mProfileFile;
745 ParcelFileDescriptor mProfileFd;
746 int mProfileType = 0;
747 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700749 final RemoteCallbackList<IActivityWatcher> mWatchers
750 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700751
752 final RemoteCallbackList<IProcessObserver> mProcessObservers
753 = new RemoteCallbackList<IProcessObserver>();
754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 /**
756 * Callback of last caller to {@link #requestPss}.
757 */
758 Runnable mRequestPssCallback;
759
760 /**
761 * Remaining processes for which we are waiting results from the last
762 * call to {@link #requestPss}.
763 */
764 final ArrayList<ProcessRecord> mRequestPssList
765 = new ArrayList<ProcessRecord>();
766
767 /**
768 * Runtime statistics collection thread. This object's lock is used to
769 * protect all related state.
770 */
771 final Thread mProcessStatsThread;
772
773 /**
774 * Used to collect process stats when showing not responding dialog.
775 * Protected by mProcessStatsThread.
776 */
777 final ProcessStats mProcessStats = new ProcessStats(
778 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700779 final AtomicLong mLastCpuTime = new AtomicLong(0);
780 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 long mLastWriteTime = 0;
783
784 /**
785 * Set to true after the system has finished booting.
786 */
787 boolean mBooted = false;
788
Dianne Hackborn7d608422011-08-07 16:24:18 -0700789 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700790 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791
792 WindowManagerService mWindowManager;
793
794 static ActivityManagerService mSelf;
795 static ActivityThread mSystemThread;
796
797 private final class AppDeathRecipient implements IBinder.DeathRecipient {
798 final ProcessRecord mApp;
799 final int mPid;
800 final IApplicationThread mAppThread;
801
802 AppDeathRecipient(ProcessRecord app, int pid,
803 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800804 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 TAG, "New death recipient " + this
806 + " for thread " + thread.asBinder());
807 mApp = app;
808 mPid = pid;
809 mAppThread = thread;
810 }
811
812 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800813 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 TAG, "Death received in " + this
815 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 synchronized(ActivityManagerService.this) {
817 appDiedLocked(mApp, mPid, mAppThread);
818 }
819 }
820 }
821
822 static final int SHOW_ERROR_MSG = 1;
823 static final int SHOW_NOT_RESPONDING_MSG = 2;
824 static final int SHOW_FACTORY_ERROR_MSG = 3;
825 static final int UPDATE_CONFIGURATION_MSG = 4;
826 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
827 static final int WAIT_FOR_DEBUGGER_MSG = 6;
828 static final int BROADCAST_INTENT_MSG = 7;
829 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 static final int SERVICE_TIMEOUT_MSG = 12;
831 static final int UPDATE_TIME_ZONE = 13;
832 static final int SHOW_UID_ERROR_MSG = 14;
833 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700835 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700836 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800837 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700838 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
839 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700840 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700841 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700842 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700843 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700844 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700845 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
846 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847
848 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700849 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850
851 final Handler mHandler = new Handler() {
852 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800853 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 //}
855
856 public void handleMessage(Message msg) {
857 switch (msg.what) {
858 case SHOW_ERROR_MSG: {
859 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 synchronized (ActivityManagerService.this) {
861 ProcessRecord proc = (ProcessRecord)data.get("app");
862 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800863 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 return;
865 }
866 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700867 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800868 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 d.show();
870 proc.crashDialog = d;
871 } else {
872 // The device is asleep, so just pretend that the user
873 // saw a crash dialog and hit "force quit".
874 res.set(0);
875 }
876 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700877
878 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 } break;
880 case SHOW_NOT_RESPONDING_MSG: {
881 synchronized (ActivityManagerService.this) {
882 HashMap data = (HashMap) msg.obj;
883 ProcessRecord proc = (ProcessRecord)data.get("app");
884 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800885 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 return;
887 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800888
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700889 Intent intent = new Intent("android.intent.action.ANR");
890 if (!mProcessesReady) {
891 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
892 }
893 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800894 null, null, 0, null, null, null,
895 false, false, MY_PID, Process.SYSTEM_UID);
896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700898 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 d.show();
900 proc.anrDialog = d;
901 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700902
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700903 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700905 case SHOW_STRICT_MODE_VIOLATION_MSG: {
906 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
907 synchronized (ActivityManagerService.this) {
908 ProcessRecord proc = (ProcessRecord) data.get("app");
909 if (proc == null) {
910 Slog.e(TAG, "App not found when showing strict mode dialog.");
911 break;
912 }
913 if (proc.crashDialog != null) {
914 Slog.e(TAG, "App already has strict mode dialog: " + proc);
915 return;
916 }
917 AppErrorResult res = (AppErrorResult) data.get("result");
918 if (!mSleeping && !mShuttingDown) {
919 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
920 d.show();
921 proc.crashDialog = d;
922 } else {
923 // The device is asleep, so just pretend that the user
924 // saw a crash dialog and hit "force quit".
925 res.set(0);
926 }
927 }
928 ensureBootCompleted();
929 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 case SHOW_FACTORY_ERROR_MSG: {
931 Dialog d = new FactoryErrorDialog(
932 mContext, msg.getData().getCharSequence("msg"));
933 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700934 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 } break;
936 case UPDATE_CONFIGURATION_MSG: {
937 final ContentResolver resolver = mContext.getContentResolver();
938 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
939 } break;
940 case GC_BACKGROUND_PROCESSES_MSG: {
941 synchronized (ActivityManagerService.this) {
942 performAppGcsIfAppropriateLocked();
943 }
944 } break;
945 case WAIT_FOR_DEBUGGER_MSG: {
946 synchronized (ActivityManagerService.this) {
947 ProcessRecord app = (ProcessRecord)msg.obj;
948 if (msg.arg1 != 0) {
949 if (!app.waitedForDebugger) {
950 Dialog d = new AppWaitingForDebuggerDialog(
951 ActivityManagerService.this,
952 mContext, app);
953 app.waitDialog = d;
954 app.waitedForDebugger = true;
955 d.show();
956 }
957 } else {
958 if (app.waitDialog != null) {
959 app.waitDialog.dismiss();
960 app.waitDialog = null;
961 }
962 }
963 }
964 } break;
965 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800966 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 TAG, "Received BROADCAST_INTENT_MSG");
968 processNextBroadcast(true);
969 } break;
970 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700971 synchronized (ActivityManagerService.this) {
972 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700976 if (mDidDexOpt) {
977 mDidDexOpt = false;
978 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
979 nmsg.obj = msg.obj;
980 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
981 return;
982 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 serviceTimeout((ProcessRecord)msg.obj);
984 } break;
985 case UPDATE_TIME_ZONE: {
986 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800987 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
988 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 if (r.thread != null) {
990 try {
991 r.thread.updateTimeZone();
992 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800993 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 }
995 }
996 }
997 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700998 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700999 case CLEAR_DNS_CACHE: {
1000 synchronized (ActivityManagerService.this) {
1001 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1002 ProcessRecord r = mLruProcesses.get(i);
1003 if (r.thread != null) {
1004 try {
1005 r.thread.clearDnsCache();
1006 } catch (RemoteException ex) {
1007 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1008 }
1009 }
1010 }
1011 }
1012 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001013 case UPDATE_HTTP_PROXY: {
1014 ProxyProperties proxy = (ProxyProperties)msg.obj;
1015 String host = "";
1016 String port = "";
1017 String exclList = "";
1018 if (proxy != null) {
1019 host = proxy.getHost();
1020 port = Integer.toString(proxy.getPort());
1021 exclList = proxy.getExclusionList();
1022 }
1023 synchronized (ActivityManagerService.this) {
1024 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1025 ProcessRecord r = mLruProcesses.get(i);
1026 if (r.thread != null) {
1027 try {
1028 r.thread.setHttpProxy(host, port, exclList);
1029 } catch (RemoteException ex) {
1030 Slog.w(TAG, "Failed to update http proxy for: " +
1031 r.info.processName);
1032 }
1033 }
1034 }
1035 }
1036 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 case SHOW_UID_ERROR_MSG: {
1038 // XXX This is a temporary dialog, no need to localize.
1039 AlertDialog d = new BaseErrorDialog(mContext);
1040 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1041 d.setCancelable(false);
1042 d.setTitle("System UIDs Inconsistent");
1043 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
Christian Mehlmauer7664e202010-07-20 08:46:17 +02001044 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1046 mUidAlert = d;
1047 d.show();
1048 } break;
1049 case IM_FEELING_LUCKY_MSG: {
1050 if (mUidAlert != null) {
1051 mUidAlert.dismiss();
1052 mUidAlert = null;
1053 }
1054 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001056 if (mDidDexOpt) {
1057 mDidDexOpt = false;
1058 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1059 nmsg.obj = msg.obj;
1060 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1061 return;
1062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 ProcessRecord app = (ProcessRecord)msg.obj;
1064 synchronized (ActivityManagerService.this) {
1065 processStartTimedOutLocked(app);
1066 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001067 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001068 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1069 synchronized (ActivityManagerService.this) {
1070 doPendingActivityLaunchesLocked(true);
1071 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001072 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001073 case KILL_APPLICATION_MSG: {
1074 synchronized (ActivityManagerService.this) {
1075 int uid = msg.arg1;
1076 boolean restart = (msg.arg2 == 1);
1077 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001078 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001079 }
1080 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001081 case FINALIZE_PENDING_INTENT_MSG: {
1082 ((PendingIntentRecord)msg.obj).completeFinalize();
1083 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001084 case POST_HEAVY_NOTIFICATION_MSG: {
1085 INotificationManager inm = NotificationManager.getService();
1086 if (inm == null) {
1087 return;
1088 }
1089
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001090 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001091 ProcessRecord process = root.app;
1092 if (process == null) {
1093 return;
1094 }
1095
1096 try {
1097 Context context = mContext.createPackageContext(process.info.packageName, 0);
1098 String text = mContext.getString(R.string.heavy_weight_notification,
1099 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1100 Notification notification = new Notification();
1101 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1102 notification.when = 0;
1103 notification.flags = Notification.FLAG_ONGOING_EVENT;
1104 notification.tickerText = text;
1105 notification.defaults = 0; // please be quiet
1106 notification.sound = null;
1107 notification.vibrate = null;
1108 notification.setLatestEventInfo(context, text,
1109 mContext.getText(R.string.heavy_weight_notification_detail),
1110 PendingIntent.getActivity(mContext, 0, root.intent,
1111 PendingIntent.FLAG_CANCEL_CURRENT));
1112
1113 try {
1114 int[] outId = new int[1];
1115 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1116 notification, outId);
1117 } catch (RuntimeException e) {
1118 Slog.w(ActivityManagerService.TAG,
1119 "Error showing notification for heavy-weight app", e);
1120 } catch (RemoteException e) {
1121 }
1122 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001123 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001124 }
1125 } break;
1126 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1127 INotificationManager inm = NotificationManager.getService();
1128 if (inm == null) {
1129 return;
1130 }
1131 try {
1132 inm.cancelNotification("android",
1133 R.string.heavy_weight_notification);
1134 } catch (RuntimeException e) {
1135 Slog.w(ActivityManagerService.TAG,
1136 "Error canceling notification for service", e);
1137 } catch (RemoteException e) {
1138 }
1139 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001140 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1141 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001142 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001143 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001144 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1145 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001146 }
1147 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001148 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1149 synchronized (ActivityManagerService.this) {
1150 ActivityRecord ar = (ActivityRecord)msg.obj;
1151 if (mCompatModeDialog != null) {
1152 if (mCompatModeDialog.mAppInfo.packageName.equals(
1153 ar.info.applicationInfo.packageName)) {
1154 return;
1155 }
1156 mCompatModeDialog.dismiss();
1157 mCompatModeDialog = null;
1158 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001159 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001160 if (mCompatModePackages.getPackageAskCompatModeLocked(
1161 ar.packageName)) {
1162 int mode = mCompatModePackages.computeCompatModeLocked(
1163 ar.info.applicationInfo);
1164 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1165 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1166 mCompatModeDialog = new CompatModeDialog(
1167 ActivityManagerService.this, mContext,
1168 ar.info.applicationInfo);
1169 mCompatModeDialog.show();
1170 }
1171 }
1172 }
1173 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001174 break;
1175 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001176 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001177 final int pid = msg.arg1;
1178 final int uid = msg.arg2;
1179 final boolean foregroundActivities = (Boolean) msg.obj;
1180 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001181 break;
1182 }
1183 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001184 final int pid = msg.arg1;
1185 final int uid = msg.arg2;
1186 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001187 break;
1188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 }
1190 }
1191 };
1192
1193 public static void setSystemProcess() {
1194 try {
1195 ActivityManagerService m = mSelf;
1196
1197 ServiceManager.addService("activity", m);
1198 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001199 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 if (MONITOR_CPU_USAGE) {
1201 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 ServiceManager.addService("permission", new PermissionController(m));
1204
1205 ApplicationInfo info =
1206 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001207 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001208 mSystemThread.installSystemApplicationInfo(info);
1209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 synchronized (mSelf) {
1211 ProcessRecord app = mSelf.newProcessRecordLocked(
1212 mSystemThread.getApplicationThread(), info,
1213 info.processName);
1214 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001215 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001216 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1218 synchronized (mSelf.mPidsSelfLocked) {
1219 mSelf.mPidsSelfLocked.put(app.pid, app);
1220 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001221 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 }
1223 } catch (PackageManager.NameNotFoundException e) {
1224 throw new RuntimeException(
1225 "Unable to find android system package", e);
1226 }
1227 }
1228
1229 public void setWindowManager(WindowManagerService wm) {
1230 mWindowManager = wm;
1231 }
1232
1233 public static final Context main(int factoryTest) {
1234 AThread thr = new AThread();
1235 thr.start();
1236
1237 synchronized (thr) {
1238 while (thr.mService == null) {
1239 try {
1240 thr.wait();
1241 } catch (InterruptedException e) {
1242 }
1243 }
1244 }
1245
1246 ActivityManagerService m = thr.mService;
1247 mSelf = m;
1248 ActivityThread at = ActivityThread.systemMain();
1249 mSystemThread = at;
1250 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001251 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 m.mContext = context;
1253 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001254 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255
1256 m.mBatteryStatsService.publish(context);
1257 m.mUsageStatsService.publish(context);
1258
1259 synchronized (thr) {
1260 thr.mReady = true;
1261 thr.notifyAll();
1262 }
1263
1264 m.startRunning(null, null, null, null);
1265
1266 return context;
1267 }
1268
1269 public static ActivityManagerService self() {
1270 return mSelf;
1271 }
1272
1273 static class AThread extends Thread {
1274 ActivityManagerService mService;
1275 boolean mReady = false;
1276
1277 public AThread() {
1278 super("ActivityManager");
1279 }
1280
1281 public void run() {
1282 Looper.prepare();
1283
1284 android.os.Process.setThreadPriority(
1285 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001286 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287
1288 ActivityManagerService m = new ActivityManagerService();
1289
1290 synchronized (this) {
1291 mService = m;
1292 notifyAll();
1293 }
1294
1295 synchronized (this) {
1296 while (!mReady) {
1297 try {
1298 wait();
1299 } catch (InterruptedException e) {
1300 }
1301 }
1302 }
1303
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001304 // For debug builds, log event loop stalls to dropbox for analysis.
1305 if (StrictMode.conditionallyEnableDebugLogging()) {
1306 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1307 }
1308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 Looper.loop();
1310 }
1311 }
1312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 static class MemBinder extends Binder {
1314 ActivityManagerService mActivityManagerService;
1315 MemBinder(ActivityManagerService activityManagerService) {
1316 mActivityManagerService = activityManagerService;
1317 }
1318
1319 @Override
1320 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001321 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 }
1323 }
1324
Chet Haase9c1e23b2011-03-24 10:51:31 -07001325 static class GraphicsBinder extends Binder {
1326 ActivityManagerService mActivityManagerService;
1327 GraphicsBinder(ActivityManagerService activityManagerService) {
1328 mActivityManagerService = activityManagerService;
1329 }
1330
1331 @Override
1332 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001333 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001334 }
1335 }
1336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 static class CpuBinder extends Binder {
1338 ActivityManagerService mActivityManagerService;
1339 CpuBinder(ActivityManagerService activityManagerService) {
1340 mActivityManagerService = activityManagerService;
1341 }
1342
1343 @Override
1344 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1345 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001346 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1347 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1348 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 }
1350 }
1351 }
1352
1353 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001354 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 File dataDir = Environment.getDataDirectory();
1357 File systemDir = new File(dataDir, "system");
1358 systemDir.mkdirs();
1359 mBatteryStatsService = new BatteryStatsService(new File(
1360 systemDir, "batterystats.bin").toString());
1361 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001362 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001363 mOnBattery = DEBUG_POWER ? true
1364 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001365 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001367 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001368 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369
Jack Palevichb90d28c2009-07-22 15:35:24 -07001370 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1371 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1372
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001373 mConfiguration.setToDefaults();
1374 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 mProcessStats.init();
1376
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001377 mCompatModePackages = new CompatModePackages(this, systemDir);
1378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 // Add ourself to the Watchdog monitors.
1380 Watchdog.getInstance().addMonitor(this);
1381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 mProcessStatsThread = new Thread("ProcessStats") {
1383 public void run() {
1384 while (true) {
1385 try {
1386 try {
1387 synchronized(this) {
1388 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001389 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001391 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 // + ", write delay=" + nextWriteDelay);
1393 if (nextWriteDelay < nextCpuDelay) {
1394 nextCpuDelay = nextWriteDelay;
1395 }
1396 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001397 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 this.wait(nextCpuDelay);
1399 }
1400 }
1401 } catch (InterruptedException e) {
1402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 updateCpuStatsNow();
1404 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001405 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 }
1407 }
1408 }
1409 };
1410 mProcessStatsThread.start();
1411 }
1412
1413 @Override
1414 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1415 throws RemoteException {
1416 try {
1417 return super.onTransact(code, data, reply, flags);
1418 } catch (RuntimeException e) {
1419 // The activity manager only throws security exceptions, so let's
1420 // log all others.
1421 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001422 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 }
1424 throw e;
1425 }
1426 }
1427
1428 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001429 final long now = SystemClock.uptimeMillis();
1430 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1431 return;
1432 }
1433 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1434 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 mProcessStatsThread.notify();
1436 }
1437 }
1438 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 void updateCpuStatsNow() {
1441 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001442 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 final long now = SystemClock.uptimeMillis();
1444 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001447 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1448 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 haveNewCpuStats = true;
1450 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001451 //Slog.i(TAG, mProcessStats.printCurrentState());
1452 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 // + mProcessStats.getTotalCpuPercent() + "%");
1454
Joe Onorato8a9b2202010-02-26 18:56:32 -08001455 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 if ("true".equals(SystemProperties.get("events.cpu"))) {
1457 int user = mProcessStats.getLastUserTime();
1458 int system = mProcessStats.getLastSystemTime();
1459 int iowait = mProcessStats.getLastIoWaitTime();
1460 int irq = mProcessStats.getLastIrqTime();
1461 int softIrq = mProcessStats.getLastSoftIrqTime();
1462 int idle = mProcessStats.getLastIdleTime();
1463
1464 int total = user + system + iowait + irq + softIrq + idle;
1465 if (total == 0) total = 1;
1466
Doug Zongker2bec3d42009-12-04 12:52:44 -08001467 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 ((user+system+iowait+irq+softIrq) * 100) / total,
1469 (user * 100) / total,
1470 (system * 100) / total,
1471 (iowait * 100) / total,
1472 (irq * 100) / total,
1473 (softIrq * 100) / total);
1474 }
1475 }
1476
Amith Yamasanie43530a2009-08-21 13:11:37 -07001477 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001478 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001479 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 synchronized(mPidsSelfLocked) {
1481 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001482 if (mOnBattery) {
1483 int perc = bstats.startAddingCpuLocked();
1484 int totalUTime = 0;
1485 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001486 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001488 ProcessStats.Stats st = mProcessStats.getStats(i);
1489 if (!st.working) {
1490 continue;
1491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001493 int otherUTime = (st.rel_utime*perc)/100;
1494 int otherSTime = (st.rel_stime*perc)/100;
1495 totalUTime += otherUTime;
1496 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 if (pr != null) {
1498 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001499 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1500 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001501 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001502 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001503 } else {
1504 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001505 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001506 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001507 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1508 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001509 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001510 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 }
1512 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001513 bstats.finishAddingCpuLocked(perc, totalUTime,
1514 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 }
1516 }
1517 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1520 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001521 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 }
1523 }
1524 }
1525 }
1526
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001527 @Override
1528 public void batteryNeedsCpuUpdate() {
1529 updateCpuStatsNow();
1530 }
1531
1532 @Override
1533 public void batteryPowerChanged(boolean onBattery) {
1534 // When plugging in, update the CPU stats first before changing
1535 // the plug state.
1536 updateCpuStatsNow();
1537 synchronized (this) {
1538 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001539 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001540 }
1541 }
1542 }
1543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 /**
1545 * Initialize the application bind args. These are passed to each
1546 * process when the bindApplication() IPC is sent to the process. They're
1547 * lazily setup to make sure the services are running when they're asked for.
1548 */
1549 private HashMap<String, IBinder> getCommonServicesLocked() {
1550 if (mAppBindArgs == null) {
1551 mAppBindArgs = new HashMap<String, IBinder>();
1552
1553 // Setup the application init args
1554 mAppBindArgs.put("package", ServiceManager.getService("package"));
1555 mAppBindArgs.put("window", ServiceManager.getService("window"));
1556 mAppBindArgs.put(Context.ALARM_SERVICE,
1557 ServiceManager.getService(Context.ALARM_SERVICE));
1558 }
1559 return mAppBindArgs;
1560 }
1561
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001562 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 if (mFocusedActivity != r) {
1564 mFocusedActivity = r;
1565 mWindowManager.setFocusedApp(r, true);
1566 }
1567 }
1568
Dianne Hackborn906497c2010-05-10 15:57:38 -07001569 private final void updateLruProcessInternalLocked(ProcessRecord app,
1570 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001572 int lrui = mLruProcesses.indexOf(app);
1573 if (lrui >= 0) mLruProcesses.remove(lrui);
1574
1575 int i = mLruProcesses.size()-1;
1576 int skipTop = 0;
1577
Dianne Hackborn906497c2010-05-10 15:57:38 -07001578 app.lruSeq = mLruSeq;
1579
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001580 // compute the new weight for this process.
1581 if (updateActivityTime) {
1582 app.lastActivityTime = SystemClock.uptimeMillis();
1583 }
1584 if (app.activities.size() > 0) {
1585 // If this process has activities, we more strongly want to keep
1586 // it around.
1587 app.lruWeight = app.lastActivityTime;
1588 } else if (app.pubProviders.size() > 0) {
1589 // If this process contains content providers, we want to keep
1590 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001591 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001592 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001593 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001594 } else {
1595 // If this process doesn't have activities, we less strongly
1596 // want to keep it around, and generally want to avoid getting
1597 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001598 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001599 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001600 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001601 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001602
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001603 while (i >= 0) {
1604 ProcessRecord p = mLruProcesses.get(i);
1605 // If this app shouldn't be in front of the first N background
1606 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001607 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001608 skipTop--;
1609 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001610 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001611 mLruProcesses.add(i+1, app);
1612 break;
1613 }
1614 i--;
1615 }
1616 if (i < 0) {
1617 mLruProcesses.add(0, app);
1618 }
1619
Dianne Hackborn906497c2010-05-10 15:57:38 -07001620 // If the app is currently using a content provider or service,
1621 // bump those processes as well.
1622 if (app.connections.size() > 0) {
1623 for (ConnectionRecord cr : app.connections) {
1624 if (cr.binding != null && cr.binding.service != null
1625 && cr.binding.service.app != null
1626 && cr.binding.service.app.lruSeq != mLruSeq) {
1627 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1628 updateActivityTime, i+1);
1629 }
1630 }
1631 }
1632 if (app.conProviders.size() > 0) {
1633 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001634 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1635 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001636 updateActivityTime, i+1);
1637 }
1638 }
1639 }
1640
Joe Onorato8a9b2202010-02-26 18:56:32 -08001641 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 if (oomAdj) {
1643 updateOomAdjLocked();
1644 }
1645 }
1646
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001647 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001648 boolean oomAdj, boolean updateActivityTime) {
1649 mLruSeq++;
1650 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1651 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001652
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001653 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 String processName, int uid) {
1655 if (uid == Process.SYSTEM_UID) {
1656 // The system gets to run in any process. If there are multiple
1657 // processes with the same uid, just pick the first (this
1658 // should never happen).
1659 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1660 processName);
1661 return procs != null ? procs.valueAt(0) : null;
1662 }
1663 ProcessRecord proc = mProcessNames.get(processName, uid);
1664 return proc;
1665 }
1666
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001667 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001668 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001669 try {
1670 if (pm.performDexOpt(packageName)) {
1671 mDidDexOpt = true;
1672 }
1673 } catch (RemoteException e) {
1674 }
1675 }
1676
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001677 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 int transit = mWindowManager.getPendingAppTransition();
1679 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1680 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1681 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1682 }
1683
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001684 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001686 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1688 // We don't have to do anything more if:
1689 // (1) There is an existing application record; and
1690 // (2) The caller doesn't think it is dead, OR there is no thread
1691 // object attached to it so we know it couldn't have crashed; and
1692 // (3) There is a pid assigned to it, so it is either starting or
1693 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001694 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 + " app=" + app + " knownToBeDead=" + knownToBeDead
1696 + " thread=" + (app != null ? app.thread : null)
1697 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001698 if (app != null && app.pid > 0) {
1699 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001700 // We already have the app running, or are waiting for it to
1701 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001702 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001703 // If this is a new package in the process, add the package to the list
1704 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001705 return app;
1706 } else {
1707 // An application record is attached to a previous process,
1708 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001709 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001710 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001712 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714 String hostingNameStr = hostingName != null
1715 ? hostingName.flattenToShortString() : null;
1716
1717 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1718 // If we are in the background, then check to see if this process
1719 // is bad. If so, we will just silently fail.
1720 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001721 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1722 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001723 return null;
1724 }
1725 } else {
1726 // When the user is explicitly starting a process, then clear its
1727 // crash count so that we won't make it bad until they see at
1728 // least one crash dialog again, and make the process good again
1729 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001730 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1731 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001732 mProcessCrashTimes.remove(info.processName, info.uid);
1733 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001734 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001735 info.processName);
1736 mBadProcesses.remove(info.processName, info.uid);
1737 if (app != null) {
1738 app.bad = false;
1739 }
1740 }
1741 }
1742
1743 if (app == null) {
1744 app = newProcessRecordLocked(null, info, processName);
1745 mProcessNames.put(processName, info.uid, app);
1746 } else {
1747 // If this is a new package in the process, add the package to the list
1748 app.addPackage(info.packageName);
1749 }
1750
1751 // If the system is not ready yet, then hold off on starting this
1752 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001753 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001754 && !isAllowedWhileBooting(info)
1755 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 if (!mProcessesOnHold.contains(app)) {
1757 mProcessesOnHold.add(app);
1758 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001759 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001760 return app;
1761 }
1762
1763 startProcessLocked(app, hostingType, hostingNameStr);
1764 return (app.pid != 0) ? app : null;
1765 }
1766
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001767 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1768 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1769 }
1770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001771 private final void startProcessLocked(ProcessRecord app,
1772 String hostingType, String hostingNameStr) {
1773 if (app.pid > 0 && app.pid != MY_PID) {
1774 synchronized (mPidsSelfLocked) {
1775 mPidsSelfLocked.remove(app.pid);
1776 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1777 }
1778 app.pid = 0;
1779 }
1780
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001781 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1782 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001783 mProcessesOnHold.remove(app);
1784
1785 updateCpuStats();
1786
1787 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1788 mProcDeaths[0] = 0;
1789
1790 try {
1791 int uid = app.info.uid;
1792 int[] gids = null;
1793 try {
1794 gids = mContext.getPackageManager().getPackageGids(
1795 app.info.packageName);
1796 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001797 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 }
1799 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1800 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1801 && mTopComponent != null
1802 && app.processName.equals(mTopComponent.getPackageName())) {
1803 uid = 0;
1804 }
1805 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1806 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1807 uid = 0;
1808 }
1809 }
1810 int debugFlags = 0;
1811 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1812 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001813 // Also turn on CheckJNI for debuggable apps. It's quite
1814 // awkward to turn on otherwise.
1815 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001817 // Run the app in safe mode if its manifest requests so or the
1818 // system is booted in safe mode.
1819 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1820 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001821 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1824 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1825 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001826 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1827 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 if ("1".equals(SystemProperties.get("debug.assert"))) {
1830 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1831 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001832
1833 // Start the process. It will either succeed and return a result containing
1834 // the PID of the new process, or else throw a RuntimeException.
1835 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001836 app.processName, uid, uid, gids, debugFlags,
1837 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1840 synchronized (bs) {
1841 if (bs.isOnBattery()) {
1842 app.batteryStats.incStartsLocked();
1843 }
1844 }
1845
Jeff Brown3f9dd282011-07-08 20:02:19 -07001846 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 app.processName, hostingType,
1848 hostingNameStr != null ? hostingNameStr : "");
1849
1850 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001851 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001852 }
1853
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001854 StringBuilder buf = mStringBuilder;
1855 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 buf.append("Start proc ");
1857 buf.append(app.processName);
1858 buf.append(" for ");
1859 buf.append(hostingType);
1860 if (hostingNameStr != null) {
1861 buf.append(" ");
1862 buf.append(hostingNameStr);
1863 }
1864 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001865 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001866 buf.append(" uid=");
1867 buf.append(uid);
1868 buf.append(" gids={");
1869 if (gids != null) {
1870 for (int gi=0; gi<gids.length; gi++) {
1871 if (gi != 0) buf.append(", ");
1872 buf.append(gids[gi]);
1873
1874 }
1875 }
1876 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001877 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001878 app.pid = startResult.pid;
1879 app.usingWrapper = startResult.usingWrapper;
1880 app.removed = false;
1881 synchronized (mPidsSelfLocked) {
1882 this.mPidsSelfLocked.put(startResult.pid, app);
1883 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1884 msg.obj = app;
1885 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1886 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 }
1888 } catch (RuntimeException e) {
1889 // XXX do better error recovery.
1890 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001891 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001892 }
1893 }
1894
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001895 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001896 if (resumed) {
1897 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1898 } else {
1899 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1900 }
1901 }
1902
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001903 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001904 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1905 && mTopAction == null) {
1906 // We are running in factory test mode, but unable to find
1907 // the factory test app, so just sit around displaying the
1908 // error message and don't try to start anything.
1909 return false;
1910 }
1911 Intent intent = new Intent(
1912 mTopAction,
1913 mTopData != null ? Uri.parse(mTopData) : null);
1914 intent.setComponent(mTopComponent);
1915 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1916 intent.addCategory(Intent.CATEGORY_HOME);
1917 }
1918 ActivityInfo aInfo =
1919 intent.resolveActivityInfo(mContext.getPackageManager(),
1920 STOCK_PM_FLAGS);
1921 if (aInfo != null) {
1922 intent.setComponent(new ComponentName(
1923 aInfo.applicationInfo.packageName, aInfo.name));
1924 // Don't do this if the home app is currently being
1925 // instrumented.
1926 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1927 aInfo.applicationInfo.uid);
1928 if (app == null || app.instrumentationClass == null) {
1929 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001930 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001931 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001932 }
1933 }
1934
1935
1936 return true;
1937 }
1938
1939 /**
1940 * Starts the "new version setup screen" if appropriate.
1941 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001942 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001943 // Only do this once per boot.
1944 if (mCheckedForSetup) {
1945 return;
1946 }
1947
1948 // We will show this screen if the current one is a different
1949 // version than the last one shown, and we are not running in
1950 // low-level factory test mode.
1951 final ContentResolver resolver = mContext.getContentResolver();
1952 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1953 Settings.Secure.getInt(resolver,
1954 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1955 mCheckedForSetup = true;
1956
1957 // See if we should be showing the platform update setup UI.
1958 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1959 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1960 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1961
1962 // We don't allow third party apps to replace this.
1963 ResolveInfo ri = null;
1964 for (int i=0; ris != null && i<ris.size(); i++) {
1965 if ((ris.get(i).activityInfo.applicationInfo.flags
1966 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1967 ri = ris.get(i);
1968 break;
1969 }
1970 }
1971
1972 if (ri != null) {
1973 String vers = ri.activityInfo.metaData != null
1974 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
1975 : null;
1976 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
1977 vers = ri.activityInfo.applicationInfo.metaData.getString(
1978 Intent.METADATA_SETUP_VERSION);
1979 }
1980 String lastVers = Settings.Secure.getString(
1981 resolver, Settings.Secure.LAST_SETUP_SHOWN);
1982 if (vers != null && !vers.equals(lastVers)) {
1983 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1984 intent.setComponent(new ComponentName(
1985 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001986 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001987 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001988 }
1989 }
1990 }
1991 }
1992
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001993 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001994 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001995 }
1996
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001997 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001998 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001999 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2000 }
2001 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002002
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002003 public void setFrontActivityScreenCompatMode(int mode) {
2004 synchronized (this) {
2005 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2006 }
2007 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002008
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002009 public int getPackageScreenCompatMode(String packageName) {
2010 synchronized (this) {
2011 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2012 }
2013 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002014
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002015 public void setPackageScreenCompatMode(String packageName, int mode) {
2016 synchronized (this) {
2017 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002018 }
2019 }
2020
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002021 public boolean getPackageAskScreenCompat(String packageName) {
2022 synchronized (this) {
2023 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2024 }
2025 }
2026
2027 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2028 synchronized (this) {
2029 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2030 }
2031 }
2032
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002033 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002034 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002035
2036 final int identHash = System.identityHashCode(r);
2037 updateUsageStats(r, true);
2038
2039 int i = mWatchers.beginBroadcast();
2040 while (i > 0) {
2041 i--;
2042 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2043 if (w != null) {
2044 try {
2045 w.activityResuming(identHash);
2046 } catch (RemoteException e) {
2047 }
2048 }
2049 }
2050 mWatchers.finishBroadcast();
2051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052
Jeff Sharkeya4620792011-05-20 15:29:23 -07002053 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2054 int i = mProcessObservers.beginBroadcast();
2055 while (i > 0) {
2056 i--;
2057 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2058 if (observer != null) {
2059 try {
2060 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2061 } catch (RemoteException e) {
2062 }
2063 }
2064 }
2065 mProcessObservers.finishBroadcast();
2066 }
2067
2068 private void dispatchProcessDied(int pid, int uid) {
2069 int i = mProcessObservers.beginBroadcast();
2070 while (i > 0) {
2071 i--;
2072 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2073 if (observer != null) {
2074 try {
2075 observer.onProcessDied(pid, uid);
2076 } catch (RemoteException e) {
2077 }
2078 }
2079 }
2080 mProcessObservers.finishBroadcast();
2081 }
2082
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002083 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002084 final int N = mPendingActivityLaunches.size();
2085 if (N <= 0) {
2086 return;
2087 }
2088 for (int i=0; i<N; i++) {
2089 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002090 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002091 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2092 doResume && i == (N-1));
2093 }
2094 mPendingActivityLaunches.clear();
2095 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002096
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002097 public final int startActivity(IApplicationThread caller,
2098 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2099 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002100 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2101 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002102 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002103 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002104 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2105 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002106 }
2107
2108 public final WaitResult startActivityAndWait(IApplicationThread caller,
2109 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2110 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002111 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2112 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002113 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002114 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002115 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002116 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2117 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002118 return res;
2119 }
2120
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002121 public final int startActivityWithConfig(IApplicationThread caller,
2122 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2123 int grantedMode, IBinder resultTo,
2124 String resultWho, int requestCode, boolean onlyIfNeeded,
2125 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002126 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002127 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002128 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002129 }
2130
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002131 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002132 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002133 IBinder resultTo, String resultWho, int requestCode,
2134 int flagsMask, int flagsValues) {
2135 // Refuse possible leaked file descriptors
2136 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2137 throw new IllegalArgumentException("File descriptors passed in Intent");
2138 }
2139
2140 IIntentSender sender = intent.getTarget();
2141 if (!(sender instanceof PendingIntentRecord)) {
2142 throw new IllegalArgumentException("Bad PendingIntent object");
2143 }
2144
2145 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002146
2147 synchronized (this) {
2148 // If this is coming from the currently resumed activity, it is
2149 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002150 if (mMainStack.mResumedActivity != null
2151 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002152 Binder.getCallingUid()) {
2153 mAppSwitchesAllowedTime = 0;
2154 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002155 }
2156
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002157 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002158 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2159 }
2160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 public boolean startNextMatchingActivity(IBinder callingActivity,
2162 Intent intent) {
2163 // Refuse possible leaked file descriptors
2164 if (intent != null && intent.hasFileDescriptors() == true) {
2165 throw new IllegalArgumentException("File descriptors passed in Intent");
2166 }
2167
2168 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002169 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2170 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 return false;
2172 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 if (r.app == null || r.app.thread == null) {
2174 // The caller is not running... d'oh!
2175 return false;
2176 }
2177 intent = new Intent(intent);
2178 // The caller is not allowed to change the data.
2179 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2180 // And we are resetting to find the next component...
2181 intent.setComponent(null);
2182
2183 ActivityInfo aInfo = null;
2184 try {
2185 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002186 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002188 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002189
2190 // Look for the original activity in the list...
2191 final int N = resolves != null ? resolves.size() : 0;
2192 for (int i=0; i<N; i++) {
2193 ResolveInfo rInfo = resolves.get(i);
2194 if (rInfo.activityInfo.packageName.equals(r.packageName)
2195 && rInfo.activityInfo.name.equals(r.info.name)) {
2196 // We found the current one... the next matching is
2197 // after it.
2198 i++;
2199 if (i<N) {
2200 aInfo = resolves.get(i).activityInfo;
2201 }
2202 break;
2203 }
2204 }
2205 } catch (RemoteException e) {
2206 }
2207
2208 if (aInfo == null) {
2209 // Nobody who is next!
2210 return false;
2211 }
2212
2213 intent.setComponent(new ComponentName(
2214 aInfo.applicationInfo.packageName, aInfo.name));
2215 intent.setFlags(intent.getFlags()&~(
2216 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2217 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2218 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2219 Intent.FLAG_ACTIVITY_NEW_TASK));
2220
2221 // Okay now we need to start the new activity, replacing the
2222 // currently running activity. This is a little tricky because
2223 // we want to start the new one as if the current one is finished,
2224 // but not finish the current one first so that there is no flicker.
2225 // And thus...
2226 final boolean wasFinishing = r.finishing;
2227 r.finishing = true;
2228
2229 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002230 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 final String resultWho = r.resultWho;
2232 final int requestCode = r.requestCode;
2233 r.resultTo = null;
2234 if (resultTo != null) {
2235 resultTo.removeResultsLocked(r, resultWho, requestCode);
2236 }
2237
2238 final long origId = Binder.clearCallingIdentity();
2239 // XXX we are not dealing with propagating grantedUriPermissions...
2240 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002241 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002242 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002243 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 Binder.restoreCallingIdentity(origId);
2245
2246 r.finishing = wasFinishing;
2247 if (res != START_SUCCESS) {
2248 return false;
2249 }
2250 return true;
2251 }
2252 }
2253
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002254 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002255 Intent intent, String resolvedType, IBinder resultTo,
2256 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002257
2258 // This is so super not safe, that only the system (or okay root)
2259 // can do it.
2260 final int callingUid = Binder.getCallingUid();
2261 if (callingUid != 0 && callingUid != Process.myUid()) {
2262 throw new SecurityException(
2263 "startActivityInPackage only available to the system");
2264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002265
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002266 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002267 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2268 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002269 }
2270
2271 public final int startActivities(IApplicationThread caller,
2272 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2273 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2274 }
2275
2276 public final int startActivitiesInPackage(int uid,
2277 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2278
2279 // This is so super not safe, that only the system (or okay root)
2280 // can do it.
2281 final int callingUid = Binder.getCallingUid();
2282 if (callingUid != 0 && callingUid != Process.myUid()) {
2283 throw new SecurityException(
2284 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 }
2286
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002287 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002288 }
2289
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002290 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002292 // Quick case: check if the top-most recent task is the same.
2293 if (N > 0 && mRecentTasks.get(0) == task) {
2294 return;
2295 }
2296 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002297 for (int i=0; i<N; i++) {
2298 TaskRecord tr = mRecentTasks.get(i);
2299 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2300 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2301 mRecentTasks.remove(i);
2302 i--;
2303 N--;
2304 if (task.intent == null) {
2305 // If the new recent task we are adding is not fully
2306 // specified, then replace it with the existing recent task.
2307 task = tr;
2308 }
2309 }
2310 }
2311 if (N >= MAX_RECENT_TASKS) {
2312 mRecentTasks.remove(N-1);
2313 }
2314 mRecentTasks.add(0, task);
2315 }
2316
2317 public void setRequestedOrientation(IBinder token,
2318 int requestedOrientation) {
2319 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002320 ActivityRecord r = mMainStack.isInStackLocked(token);
2321 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 return;
2323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324 final long origId = Binder.clearCallingIdentity();
2325 mWindowManager.setAppOrientation(r, requestedOrientation);
2326 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002327 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002328 r.mayFreezeScreenLocked(r.app) ? r : null);
2329 if (config != null) {
2330 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002331 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002332 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 }
2334 }
2335 Binder.restoreCallingIdentity(origId);
2336 }
2337 }
2338
2339 public int getRequestedOrientation(IBinder token) {
2340 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002341 ActivityRecord r = mMainStack.isInStackLocked(token);
2342 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002343 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002345 return mWindowManager.getAppOrientation(r);
2346 }
2347 }
2348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 /**
2350 * This is the internal entry point for handling Activity.finish().
2351 *
2352 * @param token The Binder token referencing the Activity we want to finish.
2353 * @param resultCode Result code, if any, from this Activity.
2354 * @param resultData Result data (Intent), if any, from this Activity.
2355 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002356 * @return Returns true if the activity successfully finished, or false if it is still running.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357 */
2358 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2359 // Refuse possible leaked file descriptors
2360 if (resultData != null && resultData.hasFileDescriptors() == true) {
2361 throw new IllegalArgumentException("File descriptors passed in Intent");
2362 }
2363
2364 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002365 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002367 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002368 if (next != null) {
2369 // ask watcher if this is allowed
2370 boolean resumeOK = true;
2371 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002372 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002373 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002374 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 }
2376
2377 if (!resumeOK) {
2378 return false;
2379 }
2380 }
2381 }
2382 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002383 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 resultData, "app-request");
2385 Binder.restoreCallingIdentity(origId);
2386 return res;
2387 }
2388 }
2389
Dianne Hackborn860755f2010-06-03 18:47:52 -07002390 public final void finishHeavyWeightApp() {
2391 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2392 != PackageManager.PERMISSION_GRANTED) {
2393 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2394 + Binder.getCallingPid()
2395 + ", uid=" + Binder.getCallingUid()
2396 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2397 Slog.w(TAG, msg);
2398 throw new SecurityException(msg);
2399 }
2400
2401 synchronized(this) {
2402 if (mHeavyWeightProcess == null) {
2403 return;
2404 }
2405
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002406 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002407 mHeavyWeightProcess.activities);
2408 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002409 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002410 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002411 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002412 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002413 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002414 null, "finish-heavy");
2415 }
2416 }
2417 }
2418
2419 mHeavyWeightProcess = null;
2420 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2421 }
2422 }
2423
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002424 public void crashApplication(int uid, int initialPid, String packageName,
2425 String message) {
2426 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2427 != PackageManager.PERMISSION_GRANTED) {
2428 String msg = "Permission Denial: crashApplication() from pid="
2429 + Binder.getCallingPid()
2430 + ", uid=" + Binder.getCallingUid()
2431 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2432 Slog.w(TAG, msg);
2433 throw new SecurityException(msg);
2434 }
2435
2436 synchronized(this) {
2437 ProcessRecord proc = null;
2438
2439 // Figure out which process to kill. We don't trust that initialPid
2440 // still has any relation to current pids, so must scan through the
2441 // list.
2442 synchronized (mPidsSelfLocked) {
2443 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2444 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2445 if (p.info.uid != uid) {
2446 continue;
2447 }
2448 if (p.pid == initialPid) {
2449 proc = p;
2450 break;
2451 }
2452 for (String str : p.pkgList) {
2453 if (str.equals(packageName)) {
2454 proc = p;
2455 }
2456 }
2457 }
2458 }
2459
2460 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002461 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002462 + " initialPid=" + initialPid
2463 + " packageName=" + packageName);
2464 return;
2465 }
2466
2467 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002468 if (proc.pid == Process.myPid()) {
2469 Log.w(TAG, "crashApplication: trying to crash self!");
2470 return;
2471 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002472 long ident = Binder.clearCallingIdentity();
2473 try {
2474 proc.thread.scheduleCrash(message);
2475 } catch (RemoteException e) {
2476 }
2477 Binder.restoreCallingIdentity(ident);
2478 }
2479 }
2480 }
2481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002482 public final void finishSubActivity(IBinder token, String resultWho,
2483 int requestCode) {
2484 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002485 ActivityRecord self = mMainStack.isInStackLocked(token);
2486 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 return;
2488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489
2490 final long origId = Binder.clearCallingIdentity();
2491
2492 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002493 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2494 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002495 if (r.resultTo == self && r.requestCode == requestCode) {
2496 if ((r.resultWho == null && resultWho == null) ||
2497 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002498 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002499 Activity.RESULT_CANCELED, null, "request-sub");
2500 }
2501 }
2502 }
2503
2504 Binder.restoreCallingIdentity(origId);
2505 }
2506 }
2507
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002508 public boolean willActivityBeVisible(IBinder token) {
2509 synchronized(this) {
2510 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002511 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2512 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002513 if (r == token) {
2514 return true;
2515 }
2516 if (r.fullscreen && !r.finishing) {
2517 return false;
2518 }
2519 }
2520 return true;
2521 }
2522 }
2523
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002524 public void overridePendingTransition(IBinder token, String packageName,
2525 int enterAnim, int exitAnim) {
2526 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002527 ActivityRecord self = mMainStack.isInStackLocked(token);
2528 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002529 return;
2530 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002531
2532 final long origId = Binder.clearCallingIdentity();
2533
2534 if (self.state == ActivityState.RESUMED
2535 || self.state == ActivityState.PAUSING) {
2536 mWindowManager.overridePendingAppTransition(packageName,
2537 enterAnim, exitAnim);
2538 }
2539
2540 Binder.restoreCallingIdentity(origId);
2541 }
2542 }
2543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002545 * Main function for removing an existing process from the activity manager
2546 * as a result of that process going away. Clears out all connections
2547 * to the process.
2548 */
2549 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002550 boolean restarting, boolean allowRestart) {
2551 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002552 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002553 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 }
2555
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002556 if (mProfileProc == app) {
2557 clearProfilerLocked();
2558 }
2559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002560 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002561 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2562 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2563 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002565 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2566 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002567 }
2568
2569 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002570 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002571
2572 boolean atTop = true;
2573 boolean hasVisibleActivities = false;
2574
2575 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002576 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002577 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 TAG, "Removing app " + app + " from history with " + i + " entries");
2579 while (i > 0) {
2580 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002581 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002582 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2584 if (r.app == app) {
2585 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002586 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002587 TAG, "Removing this entry! frozen=" + r.haveState
2588 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002589 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002590 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002591 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002592 mWindowManager.removeAppToken(r);
2593 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002594 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002595 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002596 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002597
2598 } else {
2599 // We have the current state for this activity, so
2600 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002601 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 TAG, "Keeping entry, setting app to null");
2603 if (r.visible) {
2604 hasVisibleActivities = true;
2605 }
2606 r.app = null;
2607 r.nowVisible = false;
2608 if (!r.haveState) {
2609 r.icicle = null;
2610 }
2611 }
2612
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002613 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002614 }
2615 atTop = false;
2616 }
2617
2618 app.activities.clear();
2619
2620 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002621 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 + " running instrumentation " + app.instrumentationClass);
2623 Bundle info = new Bundle();
2624 info.putString("shortMsg", "Process crashed.");
2625 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2626 }
2627
2628 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002629 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 // If there was nothing to resume, and we are not already
2631 // restarting this process, but there is a visible activity that
2632 // is hosted by the process... then make sure all visible
2633 // activities are running, taking care of restarting this
2634 // process.
2635 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002636 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637 }
2638 }
2639 }
2640 }
2641
2642 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2643 IBinder threadBinder = thread.asBinder();
2644
2645 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002646 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2647 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002648 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2649 return i;
2650 }
2651 }
2652 return -1;
2653 }
2654
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002655 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 IApplicationThread thread) {
2657 if (thread == null) {
2658 return null;
2659 }
2660
2661 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002662 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 }
2664
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002665 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 IApplicationThread thread) {
2667
2668 mProcDeaths[0]++;
2669
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002670 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2671 synchronized (stats) {
2672 stats.noteProcessDiedLocked(app.info.uid, pid);
2673 }
2674
Magnus Edlund7bb25812010-02-24 15:45:06 +01002675 // Clean up already done if the process has been re-started.
2676 if (app.pid == pid && app.thread != null &&
2677 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002678 if (!app.killedBackground) {
2679 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2680 + ") has died.");
2681 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002682 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002683 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002684 TAG, "Dying app: " + app + ", pid: " + pid
2685 + ", thread: " + thread.asBinder());
2686 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002687 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002688
2689 if (doLowMem) {
2690 // If there are no longer any background processes running,
2691 // and the app that died was not running instrumentation,
2692 // then tell everyone we are now low on memory.
2693 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002694 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2695 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002696 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697 haveBg = true;
2698 break;
2699 }
2700 }
2701
2702 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002703 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002704 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002705 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2706 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002707 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002708 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2709 // The low memory report is overriding any current
2710 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002711 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002712 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002713 rec.lastRequestedGc = 0;
2714 } else {
2715 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002717 rec.reportLowMemory = true;
2718 rec.lastLowMemory = now;
2719 mProcessesToGc.remove(rec);
2720 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721 }
2722 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002723 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 }
2725 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002726 } else if (app.pid != pid) {
2727 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002728 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002729 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002730 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002731 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002732 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 + thread.asBinder());
2734 }
2735 }
2736
Dan Egnor42471dd2010-01-07 17:25:22 -08002737 /**
2738 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002739 * @param clearTraces causes the dump file to be erased prior to the new
2740 * traces being written, if true; when false, the new traces will be
2741 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002742 * @param firstPids of dalvik VM processes to dump stack traces for first
2743 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002744 * @return file containing stack traces, or null if no dump file is configured
2745 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002746 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2747 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002748 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2749 if (tracesPath == null || tracesPath.length() == 0) {
2750 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002752
2753 File tracesFile = new File(tracesPath);
2754 try {
2755 File tracesDir = tracesFile.getParentFile();
2756 if (!tracesDir.exists()) tracesFile.mkdirs();
2757 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2758
Christopher Tate6ee412d2010-05-28 12:01:56 -07002759 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002760 tracesFile.createNewFile();
2761 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2762 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002763 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002764 return null;
2765 }
2766
2767 // Use a FileObserver to detect when traces finish writing.
2768 // The order of traces is considered important to maintain for legibility.
2769 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2770 public synchronized void onEvent(int event, String path) { notify(); }
2771 };
2772
2773 try {
2774 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002775
2776 // First collect all of the stacks of the most important pids.
2777 try {
2778 int num = firstPids.size();
2779 for (int i = 0; i < num; i++) {
2780 synchronized (observer) {
2781 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2782 observer.wait(200); // Wait for write-close, give up after 200msec
2783 }
2784 }
2785 } catch (InterruptedException e) {
2786 Log.wtf(TAG, e);
2787 }
2788
2789 // Next measure CPU usage.
2790 if (processStats != null) {
2791 processStats.init();
2792 System.gc();
2793 processStats.update();
2794 try {
2795 synchronized (processStats) {
2796 processStats.wait(500); // measure over 1/2 second.
2797 }
2798 } catch (InterruptedException e) {
2799 }
2800 processStats.update();
2801
2802 // We'll take the stack crawls of just the top apps using CPU.
2803 final int N = processStats.countWorkingStats();
2804 int numProcs = 0;
2805 for (int i=0; i<N && numProcs<5; i++) {
2806 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2807 if (lastPids.indexOfKey(stats.pid) >= 0) {
2808 numProcs++;
2809 try {
2810 synchronized (observer) {
2811 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2812 observer.wait(200); // Wait for write-close, give up after 200msec
2813 }
2814 } catch (InterruptedException e) {
2815 Log.wtf(TAG, e);
2816 }
2817
2818 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002819 }
2820 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002821
2822 return tracesFile;
2823
Dan Egnor42471dd2010-01-07 17:25:22 -08002824 } finally {
2825 observer.stopWatching();
2826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827 }
2828
Jeff Brown4d94a762010-09-23 11:33:28 -07002829 private final class AppNotResponding implements Runnable {
2830 private final ProcessRecord mApp;
2831 private final String mAnnotation;
2832
2833 public AppNotResponding(ProcessRecord app, String annotation) {
2834 mApp = app;
2835 mAnnotation = annotation;
2836 }
2837
2838 @Override
2839 public void run() {
2840 appNotResponding(mApp, null, null, mAnnotation);
2841 }
2842 }
2843
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002844 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2845 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002846 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2847 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2848
Dianne Hackborn287952c2010-09-22 22:34:31 -07002849 if (mController != null) {
2850 try {
2851 // 0 == continue, -1 = kill process immediately
2852 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2853 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2854 } catch (RemoteException e) {
2855 mController = null;
2856 }
2857 }
2858
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002859 long anrTime = SystemClock.uptimeMillis();
2860 if (MONITOR_CPU_USAGE) {
2861 updateCpuStatsNow();
2862 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002863
2864 synchronized (this) {
2865 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2866 if (mShuttingDown) {
2867 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2868 return;
2869 } else if (app.notResponding) {
2870 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2871 return;
2872 } else if (app.crashing) {
2873 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2874 return;
2875 }
2876
2877 // In case we come through here for the same app before completing
2878 // this one, mark as anring now so we will bail out.
2879 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002880
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002881 // Log the ANR to the event log.
2882 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2883 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002884
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002885 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002886 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002887
2888 int parentPid = app.pid;
2889 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002890 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002891
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002892 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002893
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002894 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2895 ProcessRecord r = mLruProcesses.get(i);
2896 if (r != null && r.thread != null) {
2897 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002898 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2899 if (r.persistent) {
2900 firstPids.add(pid);
2901 } else {
2902 lastPids.put(pid, Boolean.TRUE);
2903 }
2904 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 }
2907 }
2908
Dan Egnor42471dd2010-01-07 17:25:22 -08002909 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002910 StringBuilder info = mStringBuilder;
2911 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002912 info.append("ANR in ").append(app.processName);
2913 if (activity != null && activity.shortComponentName != null) {
2914 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002915 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002916 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002917 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002918 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002919 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002920 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002921 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923
Dianne Hackborn287952c2010-09-22 22:34:31 -07002924 final ProcessStats processStats = new ProcessStats(true);
2925
2926 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2927
Dan Egnor42471dd2010-01-07 17:25:22 -08002928 String cpuInfo = null;
2929 if (MONITOR_CPU_USAGE) {
2930 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002931 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002932 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002933 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002934 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002935 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936 }
2937
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002938 info.append(processStats.printCurrentState(anrTime));
2939
Joe Onorato8a9b2202010-02-26 18:56:32 -08002940 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002941 if (tracesFile == null) {
2942 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2943 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2944 }
2945
2946 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2947
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002948 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002949 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002950 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2951 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002952 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002953 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2954 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955 }
2956 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002957 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002958 }
2959 }
2960
Dan Egnor42471dd2010-01-07 17:25:22 -08002961 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2962 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2963 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002964
2965 synchronized (this) {
2966 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002967 Slog.w(TAG, "Killing " + app + ": background ANR");
2968 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
2969 app.processName, app.setAdj, "background ANR");
2970 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002971 return;
2972 }
2973
2974 // Set the app's notResponding state, and look up the errorReportReceiver
2975 makeAppNotRespondingLocked(app,
2976 activity != null ? activity.shortComponentName : null,
2977 annotation != null ? "ANR " + annotation : "ANR",
2978 info.toString());
2979
2980 // Bring up the infamous App Not Responding dialog
2981 Message msg = Message.obtain();
2982 HashMap map = new HashMap();
2983 msg.what = SHOW_NOT_RESPONDING_MSG;
2984 msg.obj = map;
2985 map.put("app", app);
2986 if (activity != null) {
2987 map.put("activity", activity);
2988 }
2989
2990 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08002991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 }
2993
Dianne Hackborn0dad3642010-09-09 21:25:35 -07002994 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
2995 if (!mLaunchWarningShown) {
2996 mLaunchWarningShown = true;
2997 mHandler.post(new Runnable() {
2998 @Override
2999 public void run() {
3000 synchronized (ActivityManagerService.this) {
3001 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3002 d.show();
3003 mHandler.postDelayed(new Runnable() {
3004 @Override
3005 public void run() {
3006 synchronized (ActivityManagerService.this) {
3007 d.dismiss();
3008 mLaunchWarningShown = false;
3009 }
3010 }
3011 }, 4000);
3012 }
3013 }
3014 });
3015 }
3016 }
3017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003018 public boolean clearApplicationUserData(final String packageName,
3019 final IPackageDataObserver observer) {
3020 int uid = Binder.getCallingUid();
3021 int pid = Binder.getCallingPid();
3022 long callingId = Binder.clearCallingIdentity();
3023 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003024 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 int pkgUid = -1;
3026 synchronized(this) {
3027 try {
3028 pkgUid = pm.getPackageUid(packageName);
3029 } catch (RemoteException e) {
3030 }
3031 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003032 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003033 return false;
3034 }
3035 if (uid == pkgUid || checkComponentPermission(
3036 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003037 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003039 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 } else {
3041 throw new SecurityException(pid+" does not have permission:"+
3042 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3043 "for process:"+packageName);
3044 }
3045 }
3046
3047 try {
3048 //clear application user data
3049 pm.clearApplicationUserData(packageName, observer);
3050 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3051 Uri.fromParts("package", packageName, null));
3052 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003053 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3054 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003055 } catch (RemoteException e) {
3056 }
3057 } finally {
3058 Binder.restoreCallingIdentity(callingId);
3059 }
3060 return true;
3061 }
3062
Dianne Hackborn03abb812010-01-04 18:43:19 -08003063 public void killBackgroundProcesses(final String packageName) {
3064 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3065 != PackageManager.PERMISSION_GRANTED &&
3066 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3067 != PackageManager.PERMISSION_GRANTED) {
3068 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 + Binder.getCallingPid()
3070 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003071 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003072 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 throw new SecurityException(msg);
3074 }
3075
3076 long callingId = Binder.clearCallingIdentity();
3077 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003078 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003079 int pkgUid = -1;
3080 synchronized(this) {
3081 try {
3082 pkgUid = pm.getPackageUid(packageName);
3083 } catch (RemoteException e) {
3084 }
3085 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003086 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 return;
3088 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003089 killPackageProcessesLocked(packageName, pkgUid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003090 ProcessList.SECONDARY_SERVER_ADJ, false, true, true, false);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003091 }
3092 } finally {
3093 Binder.restoreCallingIdentity(callingId);
3094 }
3095 }
3096
3097 public void forceStopPackage(final String packageName) {
3098 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3099 != PackageManager.PERMISSION_GRANTED) {
3100 String msg = "Permission Denial: forceStopPackage() from pid="
3101 + Binder.getCallingPid()
3102 + ", uid=" + Binder.getCallingUid()
3103 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003104 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003105 throw new SecurityException(msg);
3106 }
3107
3108 long callingId = Binder.clearCallingIdentity();
3109 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003110 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003111 int pkgUid = -1;
3112 synchronized(this) {
3113 try {
3114 pkgUid = pm.getPackageUid(packageName);
3115 } catch (RemoteException e) {
3116 }
3117 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003118 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003119 return;
3120 }
3121 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003122 try {
3123 pm.setPackageStoppedState(packageName, true);
3124 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003125 } catch (IllegalArgumentException e) {
3126 Slog.w(TAG, "Failed trying to unstop package "
3127 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003129 }
3130 } finally {
3131 Binder.restoreCallingIdentity(callingId);
3132 }
3133 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003134
3135 /*
3136 * The pkg name and uid have to be specified.
3137 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3138 */
3139 public void killApplicationWithUid(String pkg, int uid) {
3140 if (pkg == null) {
3141 return;
3142 }
3143 // Make sure the uid is valid.
3144 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003145 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003146 return;
3147 }
3148 int callerUid = Binder.getCallingUid();
3149 // Only the system server can kill an application
3150 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003151 // Post an aysnc message to kill the application
3152 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3153 msg.arg1 = uid;
3154 msg.arg2 = 0;
3155 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003156 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003157 } else {
3158 throw new SecurityException(callerUid + " cannot kill pkg: " +
3159 pkg);
3160 }
3161 }
3162
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003163 public void closeSystemDialogs(String reason) {
3164 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003165 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003166 if (reason != null) {
3167 intent.putExtra("reason", reason);
3168 }
3169
3170 final int uid = Binder.getCallingUid();
3171 final long origId = Binder.clearCallingIdentity();
3172 synchronized (this) {
3173 int i = mWatchers.beginBroadcast();
3174 while (i > 0) {
3175 i--;
3176 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3177 if (w != null) {
3178 try {
3179 w.closingSystemDialogs(reason);
3180 } catch (RemoteException e) {
3181 }
3182 }
3183 }
3184 mWatchers.finishBroadcast();
3185
Dianne Hackbornffa42482009-09-23 22:20:11 -07003186 mWindowManager.closeSystemDialogs(reason);
3187
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003188 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3189 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003190 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003191 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003192 Activity.RESULT_CANCELED, null, "close-sys");
3193 }
3194 }
3195
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003196 broadcastIntentLocked(null, null, intent, null,
3197 null, 0, null, null, null, false, false, -1, uid);
3198 }
3199 Binder.restoreCallingIdentity(origId);
3200 }
3201
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003202 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003203 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003204 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3205 for (int i=pids.length-1; i>=0; i--) {
3206 infos[i] = new Debug.MemoryInfo();
3207 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003208 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003209 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003210 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003211
Dianne Hackbornb437e092011-08-05 17:50:29 -07003212 public long[] getProcessPss(int[] pids) throws RemoteException {
3213 long[] pss = new long[pids.length];
3214 for (int i=pids.length-1; i>=0; i--) {
3215 pss[i] = Debug.getPss(pids[i]);
3216 }
3217 return pss;
3218 }
3219
Christopher Tate5e1ab332009-09-01 20:32:49 -07003220 public void killApplicationProcess(String processName, int uid) {
3221 if (processName == null) {
3222 return;
3223 }
3224
3225 int callerUid = Binder.getCallingUid();
3226 // Only the system server can kill an application
3227 if (callerUid == Process.SYSTEM_UID) {
3228 synchronized (this) {
3229 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003230 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003231 try {
3232 app.thread.scheduleSuicide();
3233 } catch (RemoteException e) {
3234 // If the other end already died, then our work here is done.
3235 }
3236 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003237 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003238 + processName + " / " + uid);
3239 }
3240 }
3241 } else {
3242 throw new SecurityException(callerUid + " cannot kill app process: " +
3243 processName);
3244 }
3245 }
3246
Dianne Hackborn03abb812010-01-04 18:43:19 -08003247 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003248 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003249 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3250 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003251 if (!mProcessesReady) {
3252 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003254 intent.putExtra(Intent.EXTRA_UID, uid);
3255 broadcastIntentLocked(null, null, intent,
3256 null, null, 0, null, null, null,
3257 false, false, MY_PID, Process.SYSTEM_UID);
3258 }
3259
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003260 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003261 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3262 boolean evenPersistent) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003263 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003264
Dianne Hackborn03abb812010-01-04 18:43:19 -08003265 // Remove all processes this package may have touched: all with the
3266 // same UID (except for the system or root user), and all whose name
3267 // matches the package name.
3268 final String procNamePrefix = packageName + ":";
3269 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3270 final int NA = apps.size();
3271 for (int ia=0; ia<NA; ia++) {
3272 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003273 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003274 // we don't kill persistent processes
3275 continue;
3276 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003277 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003278 if (doit) {
3279 procs.add(app);
3280 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003281 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3282 || app.processName.equals(packageName)
3283 || app.processName.startsWith(procNamePrefix)) {
3284 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003285 if (!doit) {
3286 return true;
3287 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003288 app.removed = true;
3289 procs.add(app);
3290 }
3291 }
3292 }
3293 }
3294
3295 int N = procs.size();
3296 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003297 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003298 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003299 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003300 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003301
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003302 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003303 boolean callerWillRestart, boolean purgeCache, boolean doit,
3304 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003305 int i;
3306 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003308 if (uid < 0) {
3309 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003310 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 } catch (RemoteException e) {
3312 }
3313 }
3314
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003315 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003316 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003317
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003318 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3319 while (badApps.hasNext()) {
3320 SparseArray<Long> ba = badApps.next();
3321 if (ba.get(uid) != null) {
3322 badApps.remove();
3323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 }
3325 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003326
3327 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Christopher Tate3dacd842011-08-19 14:56:15 -07003328 callerWillRestart, false, doit, evenPersistent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003330 TaskRecord lastTask = null;
3331 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003332 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003333 final boolean samePackage = r.packageName.equals(name);
3334 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003335 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003336 if (!doit) {
3337 return true;
3338 }
3339 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003340 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003341 if (samePackage) {
3342 if (r.app != null) {
3343 r.app.removed = true;
3344 }
3345 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003346 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003347 lastTask = r.task;
3348 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3349 null, "force-stop")) {
3350 i--;
3351 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003352 }
3353 }
3354
3355 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3356 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003357 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003358 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003359 if (!doit) {
3360 return true;
3361 }
3362 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003363 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003364 if (service.app != null) {
3365 service.app.removed = true;
3366 }
3367 service.app = null;
3368 services.add(service);
3369 }
3370 }
3371
3372 N = services.size();
3373 for (i=0; i<N; i++) {
3374 bringDownServiceLocked(services.get(i), true);
3375 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003376
3377 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3378 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3379 if (provider.info.packageName.equals(name)
3380 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3381 if (!doit) {
3382 return true;
3383 }
3384 didSomething = true;
3385 providers.add(provider);
3386 }
3387 }
3388
3389 N = providers.size();
3390 for (i=0; i<N; i++) {
3391 removeDyingProviderLocked(null, providers.get(i));
3392 }
3393
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003394 if (doit) {
3395 if (purgeCache) {
3396 AttributeCache ac = AttributeCache.instance();
3397 if (ac != null) {
3398 ac.removePackage(name);
3399 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003400 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003401 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003402 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003403
3404 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 }
3406
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003407 private final boolean removeProcessLocked(ProcessRecord app,
3408 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003409 final String name = app.processName;
3410 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003411 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003412 TAG, "Force removing process " + app + " (" + name
3413 + "/" + uid + ")");
3414
3415 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003416 if (mHeavyWeightProcess == app) {
3417 mHeavyWeightProcess = null;
3418 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003420 boolean needRestart = false;
3421 if (app.pid > 0 && app.pid != MY_PID) {
3422 int pid = app.pid;
3423 synchronized (mPidsSelfLocked) {
3424 mPidsSelfLocked.remove(pid);
3425 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3426 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003427 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003428 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003429 Process.killProcess(pid);
3430
3431 if (app.persistent) {
3432 if (!callerWillRestart) {
3433 addAppLocked(app.info);
3434 } else {
3435 needRestart = true;
3436 }
3437 }
3438 } else {
3439 mRemovedProcesses.add(app);
3440 }
3441
3442 return needRestart;
3443 }
3444
3445 private final void processStartTimedOutLocked(ProcessRecord app) {
3446 final int pid = app.pid;
3447 boolean gone = false;
3448 synchronized (mPidsSelfLocked) {
3449 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3450 if (knownApp != null && knownApp.thread == null) {
3451 mPidsSelfLocked.remove(pid);
3452 gone = true;
3453 }
3454 }
3455
3456 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003457 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003458 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003459 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003460 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003461 if (mHeavyWeightProcess == app) {
3462 mHeavyWeightProcess = null;
3463 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3464 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003465 // Take care of any launching providers waiting for this process.
3466 checkAppInLaunchingProvidersLocked(app, true);
3467 // Take care of any services that are waiting for the process.
3468 for (int i=0; i<mPendingServices.size(); i++) {
3469 ServiceRecord sr = mPendingServices.get(i);
3470 if (app.info.uid == sr.appInfo.uid
3471 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003472 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003473 mPendingServices.remove(i);
3474 i--;
3475 bringDownServiceLocked(sr, true);
3476 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003477 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003478 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3479 app.processName, app.setAdj, "start timeout");
3480 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003481 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003482 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003483 try {
3484 IBackupManager bm = IBackupManager.Stub.asInterface(
3485 ServiceManager.getService(Context.BACKUP_SERVICE));
3486 bm.agentDisconnected(app.info.packageName);
3487 } catch (RemoteException e) {
3488 // Can't happen; the backup manager is local
3489 }
3490 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003491 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003492 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003493 mPendingBroadcast.state = BroadcastRecord.IDLE;
3494 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003495 mPendingBroadcast = null;
3496 scheduleBroadcastsLocked();
3497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003498 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003499 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003500 }
3501 }
3502
3503 private final boolean attachApplicationLocked(IApplicationThread thread,
3504 int pid) {
3505
3506 // Find the application record that is being attached... either via
3507 // the pid if we are running in multiple processes, or just pull the
3508 // next app record if we are emulating process with anonymous threads.
3509 ProcessRecord app;
3510 if (pid != MY_PID && pid >= 0) {
3511 synchronized (mPidsSelfLocked) {
3512 app = mPidsSelfLocked.get(pid);
3513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003514 } else {
3515 app = null;
3516 }
3517
3518 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003519 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003520 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003521 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003522 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003523 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003524 } else {
3525 try {
3526 thread.scheduleExit();
3527 } catch (Exception e) {
3528 // Ignore exceptions.
3529 }
3530 }
3531 return false;
3532 }
3533
3534 // If this application record is still attached to a previous
3535 // process, clean it up now.
3536 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003537 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 }
3539
3540 // Tell the process all about itself.
3541
Joe Onorato8a9b2202010-02-26 18:56:32 -08003542 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003543 TAG, "Binding process pid " + pid + " to record " + app);
3544
3545 String processName = app.processName;
3546 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003547 AppDeathRecipient adr = new AppDeathRecipient(
3548 app, pid, thread);
3549 thread.asBinder().linkToDeath(adr, 0);
3550 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003551 } catch (RemoteException e) {
3552 app.resetPackageList();
3553 startProcessLocked(app, "link fail", processName);
3554 return false;
3555 }
3556
Doug Zongker2bec3d42009-12-04 12:52:44 -08003557 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003558
3559 app.thread = thread;
3560 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003561 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3562 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003563 app.forcingToForeground = null;
3564 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003565 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003566 app.debugging = false;
3567
3568 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3569
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003570 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003571 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003572
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003573 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003574 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003575 }
3576
Joe Onorato8a9b2202010-02-26 18:56:32 -08003577 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003578 TAG, "New app record " + app
3579 + " thread=" + thread.asBinder() + " pid=" + pid);
3580 try {
3581 int testMode = IApplicationThread.DEBUG_OFF;
3582 if (mDebugApp != null && mDebugApp.equals(processName)) {
3583 testMode = mWaitForDebugger
3584 ? IApplicationThread.DEBUG_WAIT
3585 : IApplicationThread.DEBUG_ON;
3586 app.debugging = true;
3587 if (mDebugTransient) {
3588 mDebugApp = mOrigDebugApp;
3589 mWaitForDebugger = mOrigWaitForDebugger;
3590 }
3591 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003592 String profileFile = app.instrumentationProfileFile;
3593 ParcelFileDescriptor profileFd = null;
3594 boolean profileAutoStop = false;
3595 if (mProfileApp != null && mProfileApp.equals(processName)) {
3596 mProfileProc = app;
3597 profileFile = mProfileFile;
3598 profileFd = mProfileFd;
3599 profileAutoStop = mAutoStopProfiler;
3600 }
3601
Christopher Tate181fafa2009-05-14 11:12:14 -07003602 // If the app is being launched for restore or full backup, set it up specially
3603 boolean isRestrictedBackupMode = false;
3604 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3605 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003606 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003607 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3608 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003609
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003610 ensurePackageDexOpt(app.instrumentationInfo != null
3611 ? app.instrumentationInfo.packageName
3612 : app.info.packageName);
3613 if (app.instrumentationClass != null) {
3614 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003615 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003616 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003617 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003618 ApplicationInfo appInfo = app.instrumentationInfo != null
3619 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003620 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003621 if (profileFd != null) {
3622 profileFd = profileFd.dup();
3623 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003624 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003625 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003626 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003627 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003628 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003629 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003630 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003631 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 } catch (Exception e) {
3633 // todo: Yikes! What should we do? For now we will try to
3634 // start another process, but that could easily get us in
3635 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003636 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003637
3638 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003639 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003640 startProcessLocked(app, "bind fail", processName);
3641 return false;
3642 }
3643
3644 // Remove this record from the list of starting applications.
3645 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003646 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3647 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003648 mProcessesOnHold.remove(app);
3649
3650 boolean badApp = false;
3651 boolean didSomething = false;
3652
3653 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003654 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003655 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003656 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3657 && processName.equals(hr.processName)) {
3658 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003659 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003660 didSomething = true;
3661 }
3662 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003663 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003664 + hr.intent.getComponent().flattenToShortString(), e);
3665 badApp = true;
3666 }
3667 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003668 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 }
3670 }
3671
3672 // Find any services that should be running in this process...
3673 if (!badApp && mPendingServices.size() > 0) {
3674 ServiceRecord sr = null;
3675 try {
3676 for (int i=0; i<mPendingServices.size(); i++) {
3677 sr = mPendingServices.get(i);
3678 if (app.info.uid != sr.appInfo.uid
3679 || !processName.equals(sr.processName)) {
3680 continue;
3681 }
3682
3683 mPendingServices.remove(i);
3684 i--;
3685 realStartServiceLocked(sr, app);
3686 didSomething = true;
3687 }
3688 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003689 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003690 + sr.shortName, e);
3691 badApp = true;
3692 }
3693 }
3694
3695 // Check if the next broadcast receiver is in this process...
3696 BroadcastRecord br = mPendingBroadcast;
3697 if (!badApp && br != null && br.curApp == app) {
3698 try {
3699 mPendingBroadcast = null;
3700 processCurBroadcastLocked(br, app);
3701 didSomething = true;
3702 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003703 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 + br.curComponent.flattenToShortString(), e);
3705 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003706 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3708 br.resultExtras, br.resultAbort, true);
3709 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003710 // We need to reset the state if we fails to start the receiver.
3711 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003712 }
3713 }
3714
Christopher Tate181fafa2009-05-14 11:12:14 -07003715 // Check whether the next backup agent is in this process...
3716 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003717 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003718 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003719 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003720 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3721 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3722 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003723 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003724 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003725 e.printStackTrace();
3726 }
3727 }
3728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003729 if (badApp) {
3730 // todo: Also need to kill application to deal with all
3731 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003732 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003733 return false;
3734 }
3735
3736 if (!didSomething) {
3737 updateOomAdjLocked();
3738 }
3739
3740 return true;
3741 }
3742
3743 public final void attachApplication(IApplicationThread thread) {
3744 synchronized (this) {
3745 int callingPid = Binder.getCallingPid();
3746 final long origId = Binder.clearCallingIdentity();
3747 attachApplicationLocked(thread, callingPid);
3748 Binder.restoreCallingIdentity(origId);
3749 }
3750 }
3751
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003752 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003753 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003754 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3755 if (stopProfiling) {
3756 synchronized (this) {
3757 if (mProfileProc == r.app) {
3758 if (mProfileFd != null) {
3759 try {
3760 mProfileFd.close();
3761 } catch (IOException e) {
3762 }
3763 clearProfilerLocked();
3764 }
3765 }
3766 }
3767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003768 Binder.restoreCallingIdentity(origId);
3769 }
3770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003771 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003772 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003773 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003774 mWindowManager.enableScreenAfterBoot();
3775 }
3776
Dianne Hackborn661cd522011-08-22 00:26:20 -07003777 public void showBootMessage(final CharSequence msg, final boolean always) {
3778 mWindowManager.showBootMessage(msg, always);
3779 }
3780
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003781 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003782 IntentFilter pkgFilter = new IntentFilter();
3783 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3784 pkgFilter.addDataScheme("package");
3785 mContext.registerReceiver(new BroadcastReceiver() {
3786 @Override
3787 public void onReceive(Context context, Intent intent) {
3788 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3789 if (pkgs != null) {
3790 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003791 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003792 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003793 setResultCode(Activity.RESULT_OK);
3794 return;
3795 }
3796 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003797 }
3798 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003799 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003800 }, pkgFilter);
3801
3802 synchronized (this) {
3803 // Ensure that any processes we had put on hold are now started
3804 // up.
3805 final int NP = mProcessesOnHold.size();
3806 if (NP > 0) {
3807 ArrayList<ProcessRecord> procs =
3808 new ArrayList<ProcessRecord>(mProcessesOnHold);
3809 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003810 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3811 + procs.get(ip));
3812 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003813 }
3814 }
3815
3816 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003817 // Start looking for apps that are abusing wake locks.
3818 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003819 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003820 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003821 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003822 broadcastIntentLocked(null, null,
3823 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3824 null, null, 0, null, null,
3825 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3826 false, false, MY_PID, Process.SYSTEM_UID);
3827 }
3828 }
3829 }
3830
3831 final void ensureBootCompleted() {
3832 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003833 boolean enableScreen;
3834 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003835 booting = mBooting;
3836 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003837 enableScreen = !mBooted;
3838 mBooted = true;
3839 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003840
3841 if (booting) {
3842 finishBooting();
3843 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003844
3845 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003846 enableScreenAfterBoot();
3847 }
3848 }
3849
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003850 public final void activityPaused(IBinder token) {
3851 final long origId = Binder.clearCallingIdentity();
3852 mMainStack.activityPaused(token, false);
3853 Binder.restoreCallingIdentity(origId);
3854 }
3855
3856 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3857 CharSequence description) {
3858 if (localLOGV) Slog.v(
3859 TAG, "Activity stopped: token=" + token);
3860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003861 // Refuse possible leaked file descriptors
3862 if (icicle != null && icicle.hasFileDescriptors()) {
3863 throw new IllegalArgumentException("File descriptors passed in Bundle");
3864 }
3865
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003866 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003867
3868 final long origId = Binder.clearCallingIdentity();
3869
3870 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003871 r = mMainStack.isInStackLocked(token);
3872 if (r != null) {
3873 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003874 }
3875 }
3876
3877 if (r != null) {
3878 sendPendingThumbnail(r, null, null, null, false);
3879 }
3880
3881 trimApplications();
3882
3883 Binder.restoreCallingIdentity(origId);
3884 }
3885
3886 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003887 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003888 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889 }
3890
3891 public String getCallingPackage(IBinder token) {
3892 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003893 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003894 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003895 }
3896 }
3897
3898 public ComponentName getCallingActivity(IBinder token) {
3899 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003900 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003901 return r != null ? r.intent.getComponent() : null;
3902 }
3903 }
3904
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003905 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003906 ActivityRecord r = mMainStack.isInStackLocked(token);
3907 if (r == null) {
3908 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003909 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003910 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911 }
3912
3913 public ComponentName getActivityClassForToken(IBinder token) {
3914 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003915 ActivityRecord r = mMainStack.isInStackLocked(token);
3916 if (r == null) {
3917 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003918 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003919 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003920 }
3921 }
3922
3923 public String getPackageForToken(IBinder token) {
3924 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003925 ActivityRecord r = mMainStack.isInStackLocked(token);
3926 if (r == null) {
3927 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003928 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003929 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003930 }
3931 }
3932
3933 public IIntentSender getIntentSender(int type,
3934 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003935 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003936 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003937 if (intents != null) {
3938 if (intents.length < 1) {
3939 throw new IllegalArgumentException("Intents array length must be >= 1");
3940 }
3941 for (int i=0; i<intents.length; i++) {
3942 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003943 if (intent != null) {
3944 if (intent.hasFileDescriptors()) {
3945 throw new IllegalArgumentException("File descriptors passed in Intent");
3946 }
3947 if (type == INTENT_SENDER_BROADCAST &&
3948 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3949 throw new IllegalArgumentException(
3950 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3951 }
3952 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003953 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003954 }
3955 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003956 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003957 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003958 }
3959 }
3960
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 synchronized(this) {
3962 int callingUid = Binder.getCallingUid();
3963 try {
Jeff Brown10e89712011-07-08 18:52:57 -07003964 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003965 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003966 .getPackageUid(packageName);
3967 if (uid != Binder.getCallingUid()) {
3968 String msg = "Permission Denial: getIntentSender() from pid="
3969 + Binder.getCallingPid()
3970 + ", uid=" + Binder.getCallingUid()
3971 + ", (need uid=" + uid + ")"
3972 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003973 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003974 throw new SecurityException(msg);
3975 }
3976 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003977
3978 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003979 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003980
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003981 } catch (RemoteException e) {
3982 throw new SecurityException(e);
3983 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003984 }
3985 }
3986
3987 IIntentSender getIntentSenderLocked(int type,
3988 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003989 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003990 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003991 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003992 activity = mMainStack.isInStackLocked(token);
3993 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07003994 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003995 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003996 if (activity.finishing) {
3997 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003998 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003999 }
4000
4001 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4002 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4003 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4004 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4005 |PendingIntent.FLAG_UPDATE_CURRENT);
4006
4007 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4008 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004009 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004010 WeakReference<PendingIntentRecord> ref;
4011 ref = mIntentSenderRecords.get(key);
4012 PendingIntentRecord rec = ref != null ? ref.get() : null;
4013 if (rec != null) {
4014 if (!cancelCurrent) {
4015 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004016 if (rec.key.requestIntent != null) {
4017 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4018 }
4019 if (intents != null) {
4020 intents[intents.length-1] = rec.key.requestIntent;
4021 rec.key.allIntents = intents;
4022 rec.key.allResolvedTypes = resolvedTypes;
4023 } else {
4024 rec.key.allIntents = null;
4025 rec.key.allResolvedTypes = null;
4026 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004027 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004028 return rec;
4029 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004030 rec.canceled = true;
4031 mIntentSenderRecords.remove(key);
4032 }
4033 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004034 return rec;
4035 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004036 rec = new PendingIntentRecord(this, key, callingUid);
4037 mIntentSenderRecords.put(key, rec.ref);
4038 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4039 if (activity.pendingResults == null) {
4040 activity.pendingResults
4041 = new HashSet<WeakReference<PendingIntentRecord>>();
4042 }
4043 activity.pendingResults.add(rec.ref);
4044 }
4045 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004046 }
4047
4048 public void cancelIntentSender(IIntentSender sender) {
4049 if (!(sender instanceof PendingIntentRecord)) {
4050 return;
4051 }
4052 synchronized(this) {
4053 PendingIntentRecord rec = (PendingIntentRecord)sender;
4054 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004055 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004056 .getPackageUid(rec.key.packageName);
4057 if (uid != Binder.getCallingUid()) {
4058 String msg = "Permission Denial: cancelIntentSender() from pid="
4059 + Binder.getCallingPid()
4060 + ", uid=" + Binder.getCallingUid()
4061 + " is not allowed to cancel packges "
4062 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004063 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004064 throw new SecurityException(msg);
4065 }
4066 } catch (RemoteException e) {
4067 throw new SecurityException(e);
4068 }
4069 cancelIntentSenderLocked(rec, true);
4070 }
4071 }
4072
4073 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4074 rec.canceled = true;
4075 mIntentSenderRecords.remove(rec.key);
4076 if (cleanActivity && rec.key.activity != null) {
4077 rec.key.activity.pendingResults.remove(rec.ref);
4078 }
4079 }
4080
4081 public String getPackageForIntentSender(IIntentSender pendingResult) {
4082 if (!(pendingResult instanceof PendingIntentRecord)) {
4083 return null;
4084 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004085 try {
4086 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4087 return res.key.packageName;
4088 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 }
4090 return null;
4091 }
4092
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004093 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4094 if (!(pendingResult instanceof PendingIntentRecord)) {
4095 return false;
4096 }
4097 try {
4098 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4099 if (res.key.allIntents == null) {
4100 return false;
4101 }
4102 for (int i=0; i<res.key.allIntents.length; i++) {
4103 Intent intent = res.key.allIntents[i];
4104 if (intent.getPackage() != null && intent.getComponent() != null) {
4105 return false;
4106 }
4107 }
4108 return true;
4109 } catch (ClassCastException e) {
4110 }
4111 return false;
4112 }
4113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004114 public void setProcessLimit(int max) {
4115 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4116 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004117 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004118 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004119 mProcessLimitOverride = max;
4120 }
4121 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 }
4123
4124 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004125 synchronized (this) {
4126 return mProcessLimitOverride;
4127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 }
4129
4130 void foregroundTokenDied(ForegroundToken token) {
4131 synchronized (ActivityManagerService.this) {
4132 synchronized (mPidsSelfLocked) {
4133 ForegroundToken cur
4134 = mForegroundProcesses.get(token.pid);
4135 if (cur != token) {
4136 return;
4137 }
4138 mForegroundProcesses.remove(token.pid);
4139 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4140 if (pr == null) {
4141 return;
4142 }
4143 pr.forcingToForeground = null;
4144 pr.foregroundServices = false;
4145 }
4146 updateOomAdjLocked();
4147 }
4148 }
4149
4150 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4151 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4152 "setProcessForeground()");
4153 synchronized(this) {
4154 boolean changed = false;
4155
4156 synchronized (mPidsSelfLocked) {
4157 ProcessRecord pr = mPidsSelfLocked.get(pid);
4158 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004159 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004160 return;
4161 }
4162 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4163 if (oldToken != null) {
4164 oldToken.token.unlinkToDeath(oldToken, 0);
4165 mForegroundProcesses.remove(pid);
4166 pr.forcingToForeground = null;
4167 changed = true;
4168 }
4169 if (isForeground && token != null) {
4170 ForegroundToken newToken = new ForegroundToken() {
4171 public void binderDied() {
4172 foregroundTokenDied(this);
4173 }
4174 };
4175 newToken.pid = pid;
4176 newToken.token = token;
4177 try {
4178 token.linkToDeath(newToken, 0);
4179 mForegroundProcesses.put(pid, newToken);
4180 pr.forcingToForeground = token;
4181 changed = true;
4182 } catch (RemoteException e) {
4183 // If the process died while doing this, we will later
4184 // do the cleanup with the process death link.
4185 }
4186 }
4187 }
4188
4189 if (changed) {
4190 updateOomAdjLocked();
4191 }
4192 }
4193 }
4194
4195 // =========================================================
4196 // PERMISSIONS
4197 // =========================================================
4198
4199 static class PermissionController extends IPermissionController.Stub {
4200 ActivityManagerService mActivityManagerService;
4201 PermissionController(ActivityManagerService activityManagerService) {
4202 mActivityManagerService = activityManagerService;
4203 }
4204
4205 public boolean checkPermission(String permission, int pid, int uid) {
4206 return mActivityManagerService.checkPermission(permission, pid,
4207 uid) == PackageManager.PERMISSION_GRANTED;
4208 }
4209 }
4210
4211 /**
4212 * This can be called with or without the global lock held.
4213 */
4214 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004215 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 // We might be performing an operation on behalf of an indirect binder
4217 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4218 // client identity accordingly before proceeding.
4219 Identity tlsIdentity = sCallerIdentity.get();
4220 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004221 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004222 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4223 uid = tlsIdentity.uid;
4224 pid = tlsIdentity.pid;
4225 }
4226
4227 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004228 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004229 return PackageManager.PERMISSION_GRANTED;
4230 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004231 // If there is a uid that owns whatever is being accessed, it has
4232 // blanket access to it regardless of the permissions it requires.
4233 if (owningUid >= 0 && uid == owningUid) {
4234 return PackageManager.PERMISSION_GRANTED;
4235 }
4236 // If the target is not exported, then nobody else can get to it.
4237 if (!exported) {
4238 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004239 return PackageManager.PERMISSION_DENIED;
4240 }
4241 if (permission == null) {
4242 return PackageManager.PERMISSION_GRANTED;
4243 }
4244 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004245 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004246 .checkUidPermission(permission, uid);
4247 } catch (RemoteException e) {
4248 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004249 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 }
4251 return PackageManager.PERMISSION_DENIED;
4252 }
4253
4254 /**
4255 * As the only public entry point for permissions checking, this method
4256 * can enforce the semantic that requesting a check on a null global
4257 * permission is automatically denied. (Internally a null permission
4258 * string is used when calling {@link #checkComponentPermission} in cases
4259 * when only uid-based security is needed.)
4260 *
4261 * This can be called with or without the global lock held.
4262 */
4263 public int checkPermission(String permission, int pid, int uid) {
4264 if (permission == null) {
4265 return PackageManager.PERMISSION_DENIED;
4266 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004267 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004268 }
4269
4270 /**
4271 * Binder IPC calls go through the public entry point.
4272 * This can be called with or without the global lock held.
4273 */
4274 int checkCallingPermission(String permission) {
4275 return checkPermission(permission,
4276 Binder.getCallingPid(),
4277 Binder.getCallingUid());
4278 }
4279
4280 /**
4281 * This can be called with or without the global lock held.
4282 */
4283 void enforceCallingPermission(String permission, String func) {
4284 if (checkCallingPermission(permission)
4285 == PackageManager.PERMISSION_GRANTED) {
4286 return;
4287 }
4288
4289 String msg = "Permission Denial: " + func + " from pid="
4290 + Binder.getCallingPid()
4291 + ", uid=" + Binder.getCallingUid()
4292 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004293 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004294 throw new SecurityException(msg);
4295 }
4296
4297 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004298 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4299 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4300 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4301 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4302 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004303 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004304 // Is the component private from the target uid?
4305 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4306
4307 // Acceptable if the there is no read permission needed from the
4308 // target or the target is holding the read permission.
4309 if (!readPerm) {
4310 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004311 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004312 == PackageManager.PERMISSION_GRANTED)) {
4313 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004314 }
4315 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004316
4317 // Acceptable if the there is no write permission needed from the
4318 // target or the target is holding the read permission.
4319 if (!writePerm) {
4320 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004321 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004322 == PackageManager.PERMISSION_GRANTED)) {
4323 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004324 }
4325 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004326
4327 // Acceptable if there is a path permission matching the URI that
4328 // the target holds the permission on.
4329 PathPermission[] pps = pi.pathPermissions;
4330 if (pps != null && (!readPerm || !writePerm)) {
4331 final String path = uri.getPath();
4332 int i = pps.length;
4333 while (i > 0 && (!readPerm || !writePerm)) {
4334 i--;
4335 PathPermission pp = pps[i];
4336 if (!readPerm) {
4337 final String pprperm = pp.getReadPermission();
4338 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4339 + pprperm + " for " + pp.getPath()
4340 + ": match=" + pp.match(path)
4341 + " check=" + pm.checkUidPermission(pprperm, uid));
4342 if (pprperm != null && pp.match(path) &&
4343 (pm.checkUidPermission(pprperm, uid)
4344 == PackageManager.PERMISSION_GRANTED)) {
4345 readPerm = true;
4346 }
4347 }
4348 if (!writePerm) {
4349 final String ppwperm = pp.getWritePermission();
4350 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4351 + ppwperm + " for " + pp.getPath()
4352 + ": match=" + pp.match(path)
4353 + " check=" + pm.checkUidPermission(ppwperm, uid));
4354 if (ppwperm != null && pp.match(path) &&
4355 (pm.checkUidPermission(ppwperm, uid)
4356 == PackageManager.PERMISSION_GRANTED)) {
4357 writePerm = true;
4358 }
4359 }
4360 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004362 } catch (RemoteException e) {
4363 return false;
4364 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004365
4366 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004367 }
4368
4369 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4370 int modeFlags) {
4371 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004372 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004373 return true;
4374 }
4375 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4376 if (perms == null) return false;
4377 UriPermission perm = perms.get(uri);
4378 if (perm == null) return false;
4379 return (modeFlags&perm.modeFlags) == modeFlags;
4380 }
4381
4382 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4383 // Another redirected-binder-call permissions check as in
4384 // {@link checkComponentPermission}.
4385 Identity tlsIdentity = sCallerIdentity.get();
4386 if (tlsIdentity != null) {
4387 uid = tlsIdentity.uid;
4388 pid = tlsIdentity.pid;
4389 }
4390
4391 // Our own process gets to do everything.
4392 if (pid == MY_PID) {
4393 return PackageManager.PERMISSION_GRANTED;
4394 }
4395 synchronized(this) {
4396 return checkUriPermissionLocked(uri, uid, modeFlags)
4397 ? PackageManager.PERMISSION_GRANTED
4398 : PackageManager.PERMISSION_DENIED;
4399 }
4400 }
4401
Dianne Hackborn39792d22010-08-19 18:01:52 -07004402 /**
4403 * Check if the targetPkg can be granted permission to access uri by
4404 * the callingUid using the given modeFlags. Throws a security exception
4405 * if callingUid is not allowed to do this. Returns the uid of the target
4406 * if the URI permission grant should be performed; returns -1 if it is not
4407 * needed (for example targetPkg already has permission to access the URI).
4408 */
4409 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4410 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004411 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4412 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4413 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004414 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004415 }
4416
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004417 if (targetPkg != null) {
4418 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4419 "Checking grant " + targetPkg + " permission to " + uri);
4420 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004421
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004422 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004423
4424 // If this is not a content: uri, we can't do anything with it.
4425 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004426 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004427 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004428 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004429 }
4430
4431 String name = uri.getAuthority();
4432 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004433 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004434 if (cpr != null) {
4435 pi = cpr.info;
4436 } else {
4437 try {
4438 pi = pm.resolveContentProvider(name,
4439 PackageManager.GET_URI_PERMISSION_PATTERNS);
4440 } catch (RemoteException ex) {
4441 }
4442 }
4443 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004444 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004445 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004446 }
4447
4448 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004449 if (targetPkg != null) {
4450 try {
4451 targetUid = pm.getPackageUid(targetPkg);
4452 if (targetUid < 0) {
4453 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4454 "Can't grant URI permission no uid for: " + targetPkg);
4455 return -1;
4456 }
4457 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004458 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004459 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004460 } else {
4461 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004462 }
4463
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004464 if (targetUid >= 0) {
4465 // First... does the target actually need this permission?
4466 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4467 // No need to grant the target this permission.
4468 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4469 "Target " + targetPkg + " already has full permission to " + uri);
4470 return -1;
4471 }
4472 } else {
4473 // First... there is no target package, so can anyone access it?
4474 boolean allowed = pi.exported;
4475 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4476 if (pi.readPermission != null) {
4477 allowed = false;
4478 }
4479 }
4480 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4481 if (pi.writePermission != null) {
4482 allowed = false;
4483 }
4484 }
4485 if (allowed) {
4486 return -1;
4487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004488 }
4489
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004490 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004491 if (!pi.grantUriPermissions) {
4492 throw new SecurityException("Provider " + pi.packageName
4493 + "/" + pi.name
4494 + " does not allow granting of Uri permissions (uri "
4495 + uri + ")");
4496 }
4497 if (pi.uriPermissionPatterns != null) {
4498 final int N = pi.uriPermissionPatterns.length;
4499 boolean allowed = false;
4500 for (int i=0; i<N; i++) {
4501 if (pi.uriPermissionPatterns[i] != null
4502 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4503 allowed = true;
4504 break;
4505 }
4506 }
4507 if (!allowed) {
4508 throw new SecurityException("Provider " + pi.packageName
4509 + "/" + pi.name
4510 + " does not allow granting of permission to path of Uri "
4511 + uri);
4512 }
4513 }
4514
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004515 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004516 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004517 if (callingUid != Process.myUid()) {
4518 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4519 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4520 throw new SecurityException("Uid " + callingUid
4521 + " does not have permission to uri " + uri);
4522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004523 }
4524 }
4525
Dianne Hackborn39792d22010-08-19 18:01:52 -07004526 return targetUid;
4527 }
4528
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004529 public int checkGrantUriPermission(int callingUid, String targetPkg,
4530 Uri uri, int modeFlags) {
4531 synchronized(this) {
4532 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4533 }
4534 }
4535
Dianne Hackborn39792d22010-08-19 18:01:52 -07004536 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4537 Uri uri, int modeFlags, UriPermissionOwner owner) {
4538 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4539 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4540 if (modeFlags == 0) {
4541 return;
4542 }
4543
4544 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004545 // to the uri, and the target doesn't. Let's now give this to
4546 // the target.
4547
Joe Onorato8a9b2202010-02-26 18:56:32 -08004548 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004549 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004551 HashMap<Uri, UriPermission> targetUris
4552 = mGrantedUriPermissions.get(targetUid);
4553 if (targetUris == null) {
4554 targetUris = new HashMap<Uri, UriPermission>();
4555 mGrantedUriPermissions.put(targetUid, targetUris);
4556 }
4557
4558 UriPermission perm = targetUris.get(uri);
4559 if (perm == null) {
4560 perm = new UriPermission(targetUid, uri);
4561 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004562 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004564 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004565 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004566 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004567 } else {
4568 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4569 perm.readOwners.add(owner);
4570 owner.addReadPermission(perm);
4571 }
4572 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4573 perm.writeOwners.add(owner);
4574 owner.addWritePermission(perm);
4575 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004576 }
4577 }
4578
Dianne Hackborn39792d22010-08-19 18:01:52 -07004579 void grantUriPermissionLocked(int callingUid,
4580 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004581 if (targetPkg == null) {
4582 throw new NullPointerException("targetPkg");
4583 }
4584
Dianne Hackborn39792d22010-08-19 18:01:52 -07004585 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4586 if (targetUid < 0) {
4587 return;
4588 }
4589
4590 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4591 }
4592
4593 /**
4594 * Like checkGrantUriPermissionLocked, but takes an Intent.
4595 */
4596 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4597 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004598 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004599 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004600 + " from " + intent + "; flags=0x"
4601 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4602
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004603 if (targetPkg == null) {
4604 throw new NullPointerException("targetPkg");
4605 }
4606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004607 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004608 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004609 }
4610 Uri data = intent.getData();
4611 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004612 return -1;
4613 }
4614 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4615 intent.getFlags());
4616 }
4617
4618 /**
4619 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4620 */
4621 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4622 String targetPkg, Intent intent, UriPermissionOwner owner) {
4623 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4624 intent.getFlags(), owner);
4625 }
4626
4627 void grantUriPermissionFromIntentLocked(int callingUid,
4628 String targetPkg, Intent intent, UriPermissionOwner owner) {
4629 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4630 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004631 return;
4632 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004633
4634 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004635 }
4636
4637 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4638 Uri uri, int modeFlags) {
4639 synchronized(this) {
4640 final ProcessRecord r = getRecordForAppLocked(caller);
4641 if (r == null) {
4642 throw new SecurityException("Unable to find app for caller "
4643 + caller
4644 + " when granting permission to uri " + uri);
4645 }
4646 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004647 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004648 }
4649 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004650 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004651 }
4652
4653 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4654 null);
4655 }
4656 }
4657
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004658 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004659 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4660 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4661 HashMap<Uri, UriPermission> perms
4662 = mGrantedUriPermissions.get(perm.uid);
4663 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004664 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004665 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004666 perms.remove(perm.uri);
4667 if (perms.size() == 0) {
4668 mGrantedUriPermissions.remove(perm.uid);
4669 }
4670 }
4671 }
4672 }
4673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004674 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4675 int modeFlags) {
4676 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4677 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4678 if (modeFlags == 0) {
4679 return;
4680 }
4681
Joe Onorato8a9b2202010-02-26 18:56:32 -08004682 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004683 "Revoking all granted permissions to " + uri);
4684
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004685 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004686
4687 final String authority = uri.getAuthority();
4688 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004689 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004690 if (cpr != null) {
4691 pi = cpr.info;
4692 } else {
4693 try {
4694 pi = pm.resolveContentProvider(authority,
4695 PackageManager.GET_URI_PERMISSION_PATTERNS);
4696 } catch (RemoteException ex) {
4697 }
4698 }
4699 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004700 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004701 return;
4702 }
4703
4704 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004705 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004706 // Right now, if you are not the original owner of the permission,
4707 // you are not allowed to revoke it.
4708 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4709 throw new SecurityException("Uid " + callingUid
4710 + " does not have permission to uri " + uri);
4711 //}
4712 }
4713
4714 // Go through all of the permissions and remove any that match.
4715 final List<String> SEGMENTS = uri.getPathSegments();
4716 if (SEGMENTS != null) {
4717 final int NS = SEGMENTS.size();
4718 int N = mGrantedUriPermissions.size();
4719 for (int i=0; i<N; i++) {
4720 HashMap<Uri, UriPermission> perms
4721 = mGrantedUriPermissions.valueAt(i);
4722 Iterator<UriPermission> it = perms.values().iterator();
4723 toploop:
4724 while (it.hasNext()) {
4725 UriPermission perm = it.next();
4726 Uri targetUri = perm.uri;
4727 if (!authority.equals(targetUri.getAuthority())) {
4728 continue;
4729 }
4730 List<String> targetSegments = targetUri.getPathSegments();
4731 if (targetSegments == null) {
4732 continue;
4733 }
4734 if (targetSegments.size() < NS) {
4735 continue;
4736 }
4737 for (int j=0; j<NS; j++) {
4738 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4739 continue toploop;
4740 }
4741 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004742 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004743 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004744 perm.clearModes(modeFlags);
4745 if (perm.modeFlags == 0) {
4746 it.remove();
4747 }
4748 }
4749 if (perms.size() == 0) {
4750 mGrantedUriPermissions.remove(
4751 mGrantedUriPermissions.keyAt(i));
4752 N--;
4753 i--;
4754 }
4755 }
4756 }
4757 }
4758
4759 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4760 int modeFlags) {
4761 synchronized(this) {
4762 final ProcessRecord r = getRecordForAppLocked(caller);
4763 if (r == null) {
4764 throw new SecurityException("Unable to find app for caller "
4765 + caller
4766 + " when revoking permission to uri " + uri);
4767 }
4768 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004769 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004770 return;
4771 }
4772
4773 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4774 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4775 if (modeFlags == 0) {
4776 return;
4777 }
4778
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004779 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004780
4781 final String authority = uri.getAuthority();
4782 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004783 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004784 if (cpr != null) {
4785 pi = cpr.info;
4786 } else {
4787 try {
4788 pi = pm.resolveContentProvider(authority,
4789 PackageManager.GET_URI_PERMISSION_PATTERNS);
4790 } catch (RemoteException ex) {
4791 }
4792 }
4793 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004794 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004795 return;
4796 }
4797
4798 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4799 }
4800 }
4801
Dianne Hackborn7e269642010-08-25 19:50:20 -07004802 @Override
4803 public IBinder newUriPermissionOwner(String name) {
4804 synchronized(this) {
4805 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4806 return owner.getExternalTokenLocked();
4807 }
4808 }
4809
4810 @Override
4811 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4812 Uri uri, int modeFlags) {
4813 synchronized(this) {
4814 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4815 if (owner == null) {
4816 throw new IllegalArgumentException("Unknown owner: " + token);
4817 }
4818 if (fromUid != Binder.getCallingUid()) {
4819 if (Binder.getCallingUid() != Process.myUid()) {
4820 // Only system code can grant URI permissions on behalf
4821 // of other users.
4822 throw new SecurityException("nice try");
4823 }
4824 }
4825 if (targetPkg == null) {
4826 throw new IllegalArgumentException("null target");
4827 }
4828 if (uri == null) {
4829 throw new IllegalArgumentException("null uri");
4830 }
4831
4832 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4833 }
4834 }
4835
4836 @Override
4837 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4838 synchronized(this) {
4839 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4840 if (owner == null) {
4841 throw new IllegalArgumentException("Unknown owner: " + token);
4842 }
4843
4844 if (uri == null) {
4845 owner.removeUriPermissionsLocked(mode);
4846 } else {
4847 owner.removeUriPermissionLocked(uri, mode);
4848 }
4849 }
4850 }
4851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004852 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4853 synchronized (this) {
4854 ProcessRecord app =
4855 who != null ? getRecordForAppLocked(who) : null;
4856 if (app == null) return;
4857
4858 Message msg = Message.obtain();
4859 msg.what = WAIT_FOR_DEBUGGER_MSG;
4860 msg.obj = app;
4861 msg.arg1 = waiting ? 1 : 0;
4862 mHandler.sendMessage(msg);
4863 }
4864 }
4865
4866 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004867 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4868 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004869 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004870 outInfo.threshold = homeAppMem;
4871 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4872 outInfo.hiddenAppThreshold = hiddenAppMem;
4873 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4874 ProcessList.SECONDARY_SERVER_ADJ);
4875 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4876 ProcessList.VISIBLE_APP_ADJ);
4877 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4878 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004879 }
4880
4881 // =========================================================
4882 // TASK MANAGEMENT
4883 // =========================================================
4884
4885 public List getTasks(int maxNum, int flags,
4886 IThumbnailReceiver receiver) {
4887 ArrayList list = new ArrayList();
4888
4889 PendingThumbnailsRecord pending = null;
4890 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004891 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004892
4893 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004894 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004895 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4896 + ", receiver=" + receiver);
4897
4898 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4899 != PackageManager.PERMISSION_GRANTED) {
4900 if (receiver != null) {
4901 // If the caller wants to wait for pending thumbnails,
4902 // it ain't gonna get them.
4903 try {
4904 receiver.finished();
4905 } catch (RemoteException ex) {
4906 }
4907 }
4908 String msg = "Permission Denial: getTasks() from pid="
4909 + Binder.getCallingPid()
4910 + ", uid=" + Binder.getCallingUid()
4911 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004912 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004913 throw new SecurityException(msg);
4914 }
4915
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004916 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004917 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004918 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004919 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004920 TaskRecord curTask = null;
4921 int numActivities = 0;
4922 int numRunning = 0;
4923 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004924 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004925 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004926 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004927
4928 // Initialize state for next task if needed.
4929 if (top == null ||
4930 (top.state == ActivityState.INITIALIZING
4931 && top.task == r.task)) {
4932 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 curTask = r.task;
4934 numActivities = numRunning = 0;
4935 }
4936
4937 // Add 'r' into the current task.
4938 numActivities++;
4939 if (r.app != null && r.app.thread != null) {
4940 numRunning++;
4941 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004942
Joe Onorato8a9b2202010-02-26 18:56:32 -08004943 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004944 TAG, r.intent.getComponent().flattenToShortString()
4945 + ": task=" + r.task);
4946
4947 // If the next one is a different task, generate a new
4948 // TaskInfo entry for what we have.
4949 if (next == null || next.task != curTask) {
4950 ActivityManager.RunningTaskInfo ci
4951 = new ActivityManager.RunningTaskInfo();
4952 ci.id = curTask.taskId;
4953 ci.baseActivity = r.intent.getComponent();
4954 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004955 if (top.thumbHolder != null) {
4956 ci.description = top.thumbHolder.lastDescription;
4957 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004958 ci.numActivities = numActivities;
4959 ci.numRunning = numRunning;
4960 //System.out.println(
4961 // "#" + maxNum + ": " + " descr=" + ci.description);
4962 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004963 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004964 TAG, "State=" + top.state + "Idle=" + top.idle
4965 + " app=" + top.app
4966 + " thr=" + (top.app != null ? top.app.thread : null));
4967 if (top.state == ActivityState.RESUMED
4968 || top.state == ActivityState.PAUSING) {
4969 if (top.idle && top.app != null
4970 && top.app.thread != null) {
4971 topRecord = top;
4972 topThumbnail = top.app.thread;
4973 } else {
4974 top.thumbnailNeeded = true;
4975 }
4976 }
4977 if (pending == null) {
4978 pending = new PendingThumbnailsRecord(receiver);
4979 }
4980 pending.pendingRecords.add(top);
4981 }
4982 list.add(ci);
4983 maxNum--;
4984 top = null;
4985 }
4986 }
4987
4988 if (pending != null) {
4989 mPendingThumbnails.add(pending);
4990 }
4991 }
4992
Joe Onorato8a9b2202010-02-26 18:56:32 -08004993 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004994
4995 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004996 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004997 try {
4998 topThumbnail.requestThumbnail(topRecord);
4999 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005000 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005001 sendPendingThumbnail(null, topRecord, null, null, true);
5002 }
5003 }
5004
5005 if (pending == null && receiver != null) {
5006 // In this case all thumbnails were available and the client
5007 // is being asked to be told when the remaining ones come in...
5008 // which is unusually, since the top-most currently running
5009 // activity should never have a canned thumbnail! Oh well.
5010 try {
5011 receiver.finished();
5012 } catch (RemoteException ex) {
5013 }
5014 }
5015
5016 return list;
5017 }
5018
5019 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5020 int flags) {
5021 synchronized (this) {
5022 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5023 "getRecentTasks()");
5024
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005025 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005027 final int N = mRecentTasks.size();
5028 ArrayList<ActivityManager.RecentTaskInfo> res
5029 = new ArrayList<ActivityManager.RecentTaskInfo>(
5030 maxNum < N ? maxNum : N);
5031 for (int i=0; i<N && maxNum > 0; i++) {
5032 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005033 // Return the entry if desired by the caller. We always return
5034 // the first entry, because callers always expect this to be the
5035 // forground app. We may filter others if the caller has
5036 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5037 // we should exclude the entry.
5038 if (i == 0
5039 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005040 || (tr.intent == null)
5041 || ((tr.intent.getFlags()
5042 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5043 ActivityManager.RecentTaskInfo rti
5044 = new ActivityManager.RecentTaskInfo();
5045 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005046 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005047 rti.baseIntent = new Intent(
5048 tr.intent != null ? tr.intent : tr.affinityIntent);
5049 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005050 rti.description = tr.lastDescription;
5051
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005052 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5053 // Check whether this activity is currently available.
5054 try {
5055 if (rti.origActivity != null) {
5056 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5057 continue;
5058 }
5059 } else if (rti.baseIntent != null) {
5060 if (pm.queryIntentActivities(rti.baseIntent,
5061 null, 0) == null) {
5062 continue;
5063 }
5064 }
5065 } catch (RemoteException e) {
5066 // Will never happen.
5067 }
5068 }
5069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005070 res.add(rti);
5071 maxNum--;
5072 }
5073 }
5074 return res;
5075 }
5076 }
5077
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005078 private TaskRecord taskForIdLocked(int id) {
5079 final int N = mRecentTasks.size();
5080 for (int i=0; i<N; i++) {
5081 TaskRecord tr = mRecentTasks.get(i);
5082 if (tr.taskId == id) {
5083 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005084 }
5085 }
5086 return null;
5087 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005088
5089 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5090 synchronized (this) {
5091 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5092 "getTaskThumbnails()");
5093 TaskRecord tr = taskForIdLocked(id);
5094 if (tr != null) {
5095 return mMainStack.getTaskThumbnailsLocked(tr);
5096 }
5097 }
5098 return null;
5099 }
5100
5101 public boolean removeSubTask(int taskId, int subTaskIndex) {
5102 synchronized (this) {
5103 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5104 "removeSubTask()");
5105 long ident = Binder.clearCallingIdentity();
5106 try {
5107 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5108 } finally {
5109 Binder.restoreCallingIdentity(ident);
5110 }
5111 }
5112 }
5113
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005114 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005115 TaskRecord tr = root.task;
5116 Intent baseIntent = new Intent(
5117 tr.intent != null ? tr.intent : tr.affinityIntent);
5118 ComponentName component = baseIntent.getComponent();
5119 if (component == null) {
5120 Slog.w(TAG, "Now component for base intent of task: " + tr);
5121 return;
5122 }
5123
5124 // Find any running services associated with this app.
5125 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5126 for (ServiceRecord sr : mServices.values()) {
5127 if (sr.packageName.equals(component.getPackageName())) {
5128 services.add(sr);
5129 }
5130 }
5131
5132 // Take care of any running services associated with the app.
5133 for (int i=0; i<services.size(); i++) {
5134 ServiceRecord sr = services.get(i);
5135 if (sr.startRequested) {
5136 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005137 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005138 stopServiceLocked(sr);
5139 } else {
5140 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5141 sr.makeNextStartId(), baseIntent, -1));
5142 if (sr.app != null && sr.app.thread != null) {
5143 sendServiceArgsLocked(sr, false);
5144 }
5145 }
5146 }
5147 }
5148
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005149 if (killProcesses) {
5150 // Find any running processes associated with this app.
5151 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5152 SparseArray<ProcessRecord> appProcs
5153 = mProcessNames.getMap().get(component.getPackageName());
5154 if (appProcs != null) {
5155 for (int i=0; i<appProcs.size(); i++) {
5156 procs.add(appProcs.valueAt(i));
5157 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005158 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005159
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005160 // Kill the running processes.
5161 for (int i=0; i<procs.size(); i++) {
5162 ProcessRecord pr = procs.get(i);
5163 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5164 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5165 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5166 pr.processName, pr.setAdj, "remove task");
5167 Process.killProcessQuiet(pr.pid);
5168 } else {
5169 pr.waitingToKill = "remove task";
5170 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005171 }
5172 }
5173 }
5174
5175 public boolean removeTask(int taskId, int flags) {
5176 synchronized (this) {
5177 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5178 "removeTask()");
5179 long ident = Binder.clearCallingIdentity();
5180 try {
5181 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5182 if (r != null) {
5183 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005184 cleanUpRemovedTaskLocked(r,
5185 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005186 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005187 } else {
5188 TaskRecord tr = null;
5189 int i=0;
5190 while (i < mRecentTasks.size()) {
5191 TaskRecord t = mRecentTasks.get(i);
5192 if (t.taskId == taskId) {
5193 tr = t;
5194 break;
5195 }
5196 i++;
5197 }
5198 if (tr != null) {
5199 if (tr.numActivities <= 0) {
5200 // Caller is just removing a recent task that is
5201 // not actively running. That is easy!
5202 mRecentTasks.remove(i);
5203 } else {
5204 Slog.w(TAG, "removeTask: task " + taskId
5205 + " does not have activities to remove, "
5206 + " but numActivities=" + tr.numActivities
5207 + ": " + tr);
5208 }
5209 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005210 }
5211 } finally {
5212 Binder.restoreCallingIdentity(ident);
5213 }
5214 }
5215 return false;
5216 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5219 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005220 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005221 TaskRecord jt = startTask;
5222
5223 // First look backwards
5224 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005225 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005226 if (r.task != jt) {
5227 jt = r.task;
5228 if (affinity.equals(jt.affinity)) {
5229 return j;
5230 }
5231 }
5232 }
5233
5234 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005235 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005236 jt = startTask;
5237 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005238 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005239 if (r.task != jt) {
5240 if (affinity.equals(jt.affinity)) {
5241 return j;
5242 }
5243 jt = r.task;
5244 }
5245 }
5246
5247 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005248 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005249 return N-1;
5250 }
5251
5252 return -1;
5253 }
5254
5255 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005256 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005257 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005258 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005259 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5260 "moveTaskToFront()");
5261
5262 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005263 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5264 Binder.getCallingUid(), "Task to front")) {
5265 return;
5266 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005267 final long origId = Binder.clearCallingIdentity();
5268 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005269 TaskRecord tr = taskForIdLocked(task);
5270 if (tr != null) {
5271 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5272 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005273 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005274 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5275 // Caller wants the home activity moved with it. To accomplish this,
5276 // we'll just move the home task to the top first.
5277 mMainStack.moveHomeToFrontLocked();
5278 }
5279 mMainStack.moveTaskToFrontLocked(tr, null);
5280 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005281 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005282 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5283 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005284 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005285 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5286 mMainStack.mUserLeaving = true;
5287 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005288 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5289 // Caller wants the home activity moved with it. To accomplish this,
5290 // we'll just move the home task to the top first.
5291 mMainStack.moveHomeToFrontLocked();
5292 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005293 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005294 return;
5295 }
5296 }
5297 } finally {
5298 Binder.restoreCallingIdentity(origId);
5299 }
5300 }
5301 }
5302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005303 public void moveTaskToBack(int task) {
5304 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5305 "moveTaskToBack()");
5306
5307 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005308 if (mMainStack.mResumedActivity != null
5309 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005310 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5311 Binder.getCallingUid(), "Task to back")) {
5312 return;
5313 }
5314 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005315 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005316 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005317 Binder.restoreCallingIdentity(origId);
5318 }
5319 }
5320
5321 /**
5322 * Moves an activity, and all of the other activities within the same task, to the bottom
5323 * of the history stack. The activity's order within the task is unchanged.
5324 *
5325 * @param token A reference to the activity we wish to move
5326 * @param nonRoot If false then this only works if the activity is the root
5327 * of a task; if true it will work for any activity in a task.
5328 * @return Returns true if the move completed, false if not.
5329 */
5330 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5331 synchronized(this) {
5332 final long origId = Binder.clearCallingIdentity();
5333 int taskId = getTaskForActivityLocked(token, !nonRoot);
5334 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005335 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005336 }
5337 Binder.restoreCallingIdentity(origId);
5338 }
5339 return false;
5340 }
5341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005342 public void moveTaskBackwards(int task) {
5343 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5344 "moveTaskBackwards()");
5345
5346 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005347 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5348 Binder.getCallingUid(), "Task backwards")) {
5349 return;
5350 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005351 final long origId = Binder.clearCallingIdentity();
5352 moveTaskBackwardsLocked(task);
5353 Binder.restoreCallingIdentity(origId);
5354 }
5355 }
5356
5357 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005358 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005359 }
5360
5361 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5362 synchronized(this) {
5363 return getTaskForActivityLocked(token, onlyRoot);
5364 }
5365 }
5366
5367 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005368 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005369 TaskRecord lastTask = null;
5370 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005371 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005372 if (r == token) {
5373 if (!onlyRoot || lastTask != r.task) {
5374 return r.task.taskId;
5375 }
5376 return -1;
5377 }
5378 lastTask = r.task;
5379 }
5380
5381 return -1;
5382 }
5383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005384 public void finishOtherInstances(IBinder token, ComponentName className) {
5385 synchronized(this) {
5386 final long origId = Binder.clearCallingIdentity();
5387
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005388 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005389 TaskRecord lastTask = null;
5390 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005391 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005392 if (r.realActivity.equals(className)
5393 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005394 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005395 null, "others")) {
5396 i--;
5397 N--;
5398 }
5399 }
5400 lastTask = r.task;
5401 }
5402
5403 Binder.restoreCallingIdentity(origId);
5404 }
5405 }
5406
5407 // =========================================================
5408 // THUMBNAILS
5409 // =========================================================
5410
5411 public void reportThumbnail(IBinder token,
5412 Bitmap thumbnail, CharSequence description) {
5413 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5414 final long origId = Binder.clearCallingIdentity();
5415 sendPendingThumbnail(null, token, thumbnail, description, true);
5416 Binder.restoreCallingIdentity(origId);
5417 }
5418
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005419 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005420 Bitmap thumbnail, CharSequence description, boolean always) {
5421 TaskRecord task = null;
5422 ArrayList receivers = null;
5423
5424 //System.out.println("Send pending thumbnail: " + r);
5425
5426 synchronized(this) {
5427 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005428 r = mMainStack.isInStackLocked(token);
5429 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005430 return;
5431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005433 if (thumbnail == null && r.thumbHolder != null) {
5434 thumbnail = r.thumbHolder.lastThumbnail;
5435 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005436 }
5437 if (thumbnail == null && !always) {
5438 // If there is no thumbnail, and this entry is not actually
5439 // going away, then abort for now and pick up the next
5440 // thumbnail we get.
5441 return;
5442 }
5443 task = r.task;
5444
5445 int N = mPendingThumbnails.size();
5446 int i=0;
5447 while (i<N) {
5448 PendingThumbnailsRecord pr =
5449 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5450 //System.out.println("Looking in " + pr.pendingRecords);
5451 if (pr.pendingRecords.remove(r)) {
5452 if (receivers == null) {
5453 receivers = new ArrayList();
5454 }
5455 receivers.add(pr);
5456 if (pr.pendingRecords.size() == 0) {
5457 pr.finished = true;
5458 mPendingThumbnails.remove(i);
5459 N--;
5460 continue;
5461 }
5462 }
5463 i++;
5464 }
5465 }
5466
5467 if (receivers != null) {
5468 final int N = receivers.size();
5469 for (int i=0; i<N; i++) {
5470 try {
5471 PendingThumbnailsRecord pr =
5472 (PendingThumbnailsRecord)receivers.get(i);
5473 pr.receiver.newThumbnail(
5474 task != null ? task.taskId : -1, thumbnail, description);
5475 if (pr.finished) {
5476 pr.receiver.finished();
5477 }
5478 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005479 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005480 }
5481 }
5482 }
5483 }
5484
5485 // =========================================================
5486 // CONTENT PROVIDERS
5487 // =========================================================
5488
Jeff Brown10e89712011-07-08 18:52:57 -07005489 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5490 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005491 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005492 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005493 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005494 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005495 } catch (RemoteException ex) {
5496 }
5497 if (providers != null) {
5498 final int N = providers.size();
5499 for (int i=0; i<N; i++) {
5500 ProviderInfo cpi =
5501 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005502 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5503 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005504 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005505 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005506 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005507 }
5508 app.pubProviders.put(cpi.name, cpr);
5509 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005510 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005511 }
5512 }
5513 return providers;
5514 }
5515
5516 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005517 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005518 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5519 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5520 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005521 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005522 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005523 return null;
5524 }
5525 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005526 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005527 == PackageManager.PERMISSION_GRANTED) {
5528 return null;
5529 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005530
5531 PathPermission[] pps = cpi.pathPermissions;
5532 if (pps != null) {
5533 int i = pps.length;
5534 while (i > 0) {
5535 i--;
5536 PathPermission pp = pps[i];
5537 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005538 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005539 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005540 return null;
5541 }
5542 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005543 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005544 == PackageManager.PERMISSION_GRANTED) {
5545 return null;
5546 }
5547 }
5548 }
5549
Dianne Hackbornb424b632010-08-18 15:59:05 -07005550 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5551 if (perms != null) {
5552 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5553 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5554 return null;
5555 }
5556 }
5557 }
5558
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005559 String msg;
5560 if (!cpi.exported) {
5561 msg = "Permission Denial: opening provider " + cpi.name
5562 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5563 + ", uid=" + callingUid + ") that is not exported from uid "
5564 + cpi.applicationInfo.uid;
5565 } else {
5566 msg = "Permission Denial: opening provider " + cpi.name
5567 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5568 + ", uid=" + callingUid + ") requires "
5569 + cpi.readPermission + " or " + cpi.writePermission;
5570 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005571 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005572 return msg;
5573 }
5574
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005575 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5576 if (r != null) {
5577 Integer cnt = r.conProviders.get(cpr);
5578 if (DEBUG_PROVIDER) Slog.v(TAG,
5579 "Adding provider requested by "
5580 + r.processName + " from process "
5581 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5582 + " cnt=" + (cnt == null ? 1 : cnt));
5583 if (cnt == null) {
5584 cpr.clients.add(r);
5585 r.conProviders.put(cpr, new Integer(1));
5586 return true;
5587 } else {
5588 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5589 }
5590 } else {
5591 cpr.externals++;
5592 }
5593 return false;
5594 }
5595
5596 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5597 if (r != null) {
5598 Integer cnt = r.conProviders.get(cpr);
5599 if (DEBUG_PROVIDER) Slog.v(TAG,
5600 "Removing provider requested by "
5601 + r.processName + " from process "
5602 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5603 + " cnt=" + cnt);
5604 if (cnt == null || cnt.intValue() <= 1) {
5605 cpr.clients.remove(r);
5606 r.conProviders.remove(cpr);
5607 return true;
5608 } else {
5609 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5610 }
5611 } else {
5612 cpr.externals++;
5613 }
5614 return false;
5615 }
5616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005617 private final ContentProviderHolder getContentProviderImpl(
5618 IApplicationThread caller, String name) {
5619 ContentProviderRecord cpr;
5620 ProviderInfo cpi = null;
5621
5622 synchronized(this) {
5623 ProcessRecord r = null;
5624 if (caller != null) {
5625 r = getRecordForAppLocked(caller);
5626 if (r == null) {
5627 throw new SecurityException(
5628 "Unable to find app for caller " + caller
5629 + " (pid=" + Binder.getCallingPid()
5630 + ") when getting content provider " + name);
5631 }
5632 }
5633
5634 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005635 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005636 boolean providerRunning = cpr != null;
5637 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005638 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005639 String msg;
5640 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5641 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005642 }
5643
5644 if (r != null && cpr.canRunHere(r)) {
5645 // This provider has been published or is in the process
5646 // of being published... but it is also allowed to run
5647 // in the caller's process, so don't make a connection
5648 // and just let the caller instantiate its own instance.
5649 if (cpr.provider != null) {
5650 // don't give caller the provider object, it needs
5651 // to make its own.
5652 cpr = new ContentProviderRecord(cpr);
5653 }
5654 return cpr;
5655 }
5656
5657 final long origId = Binder.clearCallingIdentity();
5658
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005659 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005660 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005661 final boolean countChanged = incProviderCount(r, cpr);
5662 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005663 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005664 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005665 // make sure to count it as being accessed and thus
5666 // back up on the LRU list. This is good because
5667 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005668 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005669 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005670 }
5671
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005672 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005673 if (false) {
5674 if (cpr.name.flattenToShortString().equals(
5675 "com.android.providers.calendar/.CalendarProvider2")) {
5676 Slog.v(TAG, "****************** KILLING "
5677 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005678 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005679 }
5680 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005681 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005682 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5683 // NOTE: there is still a race here where a signal could be
5684 // pending on the process even though we managed to update its
5685 // adj level. Not sure what to do about this, but at least
5686 // the race is now smaller.
5687 if (!success) {
5688 // Uh oh... it looks like the provider's process
5689 // has been killed on us. We need to wait for a new
5690 // process to be started, and make sure its death
5691 // doesn't kill our process.
5692 Slog.i(TAG,
5693 "Existing provider " + cpr.name.flattenToShortString()
5694 + " is crashing; detaching " + r);
5695 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005696 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005697 if (!lastRef) {
5698 // This wasn't the last ref our process had on
5699 // the provider... we have now been killed, bail.
5700 return null;
5701 }
5702 providerRunning = false;
5703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005704 }
5705
5706 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005707 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005708
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005709 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005710 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005711 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005712 resolveContentProvider(name,
5713 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005714 } catch (RemoteException ex) {
5715 }
5716 if (cpi == null) {
5717 return null;
5718 }
5719
Dianne Hackbornb424b632010-08-18 15:59:05 -07005720 String msg;
5721 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5722 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005723 }
5724
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005725 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005726 && !cpi.processName.equals("system")) {
5727 // If this content provider does not run in the system
5728 // process, and the system is not yet ready to run other
5729 // processes, then fail fast instead of hanging.
5730 throw new IllegalArgumentException(
5731 "Attempt to launch content provider before system ready");
5732 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005733
5734 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5735 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005736 final boolean firstClass = cpr == null;
5737 if (firstClass) {
5738 try {
5739 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005740 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005741 getApplicationInfo(
5742 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005743 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005744 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005745 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005746 + cpi.name);
5747 return null;
5748 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005749 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005750 } catch (RemoteException ex) {
5751 // pm is in same process, this will never happen.
5752 }
5753 }
5754
5755 if (r != null && cpr.canRunHere(r)) {
5756 // If this is a multiprocess provider, then just return its
5757 // info and allow the caller to instantiate it. Only do
5758 // this if the provider is the same user as the caller's
5759 // process, or can run as root (so can be in any process).
5760 return cpr;
5761 }
5762
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005763 if (DEBUG_PROVIDER) {
5764 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005765 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005766 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005767 }
5768
5769 // This is single process, and our app is now connecting to it.
5770 // See if we are already in the process of launching this
5771 // provider.
5772 final int N = mLaunchingProviders.size();
5773 int i;
5774 for (i=0; i<N; i++) {
5775 if (mLaunchingProviders.get(i) == cpr) {
5776 break;
5777 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005778 }
5779
5780 // If the provider is not already being launched, then get it
5781 // started.
5782 if (i >= N) {
5783 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005784
5785 try {
5786 // Content provider is now in use, its package can't be stopped.
5787 try {
5788 AppGlobals.getPackageManager().setPackageStoppedState(
5789 cpr.appInfo.packageName, false);
5790 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005791 } catch (IllegalArgumentException e) {
5792 Slog.w(TAG, "Failed trying to unstop package "
5793 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005794 }
5795
5796 ProcessRecord proc = startProcessLocked(cpi.processName,
5797 cpr.appInfo, false, 0, "content provider",
5798 new ComponentName(cpi.applicationInfo.packageName,
5799 cpi.name), false);
5800 if (proc == null) {
5801 Slog.w(TAG, "Unable to launch app "
5802 + cpi.applicationInfo.packageName + "/"
5803 + cpi.applicationInfo.uid + " for provider "
5804 + name + ": process is bad");
5805 return null;
5806 }
5807 cpr.launchingApp = proc;
5808 mLaunchingProviders.add(cpr);
5809 } finally {
5810 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005811 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005812 }
5813
5814 // Make sure the provider is published (the same provider class
5815 // may be published under multiple names).
5816 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005817 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005818 }
5819 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005820 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005821 }
5822 }
5823
5824 // Wait for the provider to be published...
5825 synchronized (cpr) {
5826 while (cpr.provider == null) {
5827 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005828 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005829 + cpi.applicationInfo.packageName + "/"
5830 + cpi.applicationInfo.uid + " for provider "
5831 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005832 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005833 cpi.applicationInfo.packageName,
5834 cpi.applicationInfo.uid, name);
5835 return null;
5836 }
5837 try {
5838 cpr.wait();
5839 } catch (InterruptedException ex) {
5840 }
5841 }
5842 }
5843 return cpr;
5844 }
5845
5846 public final ContentProviderHolder getContentProvider(
5847 IApplicationThread caller, String name) {
5848 if (caller == null) {
5849 String msg = "null IApplicationThread when getting content provider "
5850 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005851 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005852 throw new SecurityException(msg);
5853 }
5854
5855 return getContentProviderImpl(caller, name);
5856 }
5857
5858 private ContentProviderHolder getContentProviderExternal(String name) {
5859 return getContentProviderImpl(null, name);
5860 }
5861
5862 /**
5863 * Drop a content provider from a ProcessRecord's bookkeeping
5864 * @param cpr
5865 */
5866 public void removeContentProvider(IApplicationThread caller, String name) {
5867 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005868 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005869 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005870 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005871 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005872 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005873 return;
5874 }
5875 final ProcessRecord r = getRecordForAppLocked(caller);
5876 if (r == null) {
5877 throw new SecurityException(
5878 "Unable to find app for caller " + caller +
5879 " when removing content provider " + name);
5880 }
5881 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005882 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5883 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005884 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005885 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005886 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005887 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005888 return;
5889 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005890 if (decProviderCount(r, localCpr)) {
5891 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005893 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005894 }
5895 }
5896
5897 private void removeContentProviderExternal(String name) {
5898 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005899 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005900 if(cpr == null) {
5901 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005902 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005903 return;
5904 }
5905
5906 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005907 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5908 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005909 localCpr.externals--;
5910 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005911 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005912 }
5913 updateOomAdjLocked();
5914 }
5915 }
5916
5917 public final void publishContentProviders(IApplicationThread caller,
5918 List<ContentProviderHolder> providers) {
5919 if (providers == null) {
5920 return;
5921 }
5922
5923 synchronized(this) {
5924 final ProcessRecord r = getRecordForAppLocked(caller);
5925 if (r == null) {
5926 throw new SecurityException(
5927 "Unable to find app for caller " + caller
5928 + " (pid=" + Binder.getCallingPid()
5929 + ") when publishing content providers");
5930 }
5931
5932 final long origId = Binder.clearCallingIdentity();
5933
5934 final int N = providers.size();
5935 for (int i=0; i<N; i++) {
5936 ContentProviderHolder src = providers.get(i);
5937 if (src == null || src.info == null || src.provider == null) {
5938 continue;
5939 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005940 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005941 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005942 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
5943 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005944 String names[] = dst.info.authority.split(";");
5945 for (int j = 0; j < names.length; j++) {
5946 mProvidersByName.put(names[j], dst);
5947 }
5948
5949 int NL = mLaunchingProviders.size();
5950 int j;
5951 for (j=0; j<NL; j++) {
5952 if (mLaunchingProviders.get(j) == dst) {
5953 mLaunchingProviders.remove(j);
5954 j--;
5955 NL--;
5956 }
5957 }
5958 synchronized (dst) {
5959 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005960 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005961 dst.notifyAll();
5962 }
5963 updateOomAdjLocked(r);
5964 }
5965 }
5966
5967 Binder.restoreCallingIdentity(origId);
5968 }
5969 }
5970
5971 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07005972 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005973 synchronized (mSelf) {
5974 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5975 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005976 if (providers != null) {
5977 for (int i=providers.size()-1; i>=0; i--) {
5978 ProviderInfo pi = (ProviderInfo)providers.get(i);
5979 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5980 Slog.w(TAG, "Not installing system proc provider " + pi.name
5981 + ": not system .apk");
5982 providers.remove(i);
5983 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005984 }
5985 }
5986 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005987 if (providers != null) {
5988 mSystemThread.installSystemProviders(providers);
5989 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005990
5991 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01005992
5993 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005994 }
5995
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005996 /**
5997 * Allows app to retrieve the MIME type of a URI without having permission
5998 * to access its content provider.
5999 *
6000 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6001 *
6002 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6003 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6004 */
6005 public String getProviderMimeType(Uri uri) {
6006 final String name = uri.getAuthority();
6007 final long ident = Binder.clearCallingIdentity();
6008 ContentProviderHolder holder = null;
6009
6010 try {
6011 holder = getContentProviderExternal(name);
6012 if (holder != null) {
6013 return holder.provider.getType(uri);
6014 }
6015 } catch (RemoteException e) {
6016 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6017 return null;
6018 } finally {
6019 if (holder != null) {
6020 removeContentProviderExternal(name);
6021 }
6022 Binder.restoreCallingIdentity(ident);
6023 }
6024
6025 return null;
6026 }
6027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006028 // =========================================================
6029 // GLOBAL MANAGEMENT
6030 // =========================================================
6031
6032 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6033 ApplicationInfo info, String customProcess) {
6034 String proc = customProcess != null ? customProcess : info.processName;
6035 BatteryStatsImpl.Uid.Proc ps = null;
6036 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6037 synchronized (stats) {
6038 ps = stats.getProcessStatsLocked(info.uid, proc);
6039 }
6040 return new ProcessRecord(ps, thread, info, proc);
6041 }
6042
6043 final ProcessRecord addAppLocked(ApplicationInfo info) {
6044 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6045
6046 if (app == null) {
6047 app = newProcessRecordLocked(null, info, null);
6048 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006049 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006050 }
6051
Dianne Hackborne7f97212011-02-24 14:40:20 -08006052 // This package really, really can not be stopped.
6053 try {
6054 AppGlobals.getPackageManager().setPackageStoppedState(
6055 info.packageName, false);
6056 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006057 } catch (IllegalArgumentException e) {
6058 Slog.w(TAG, "Failed trying to unstop package "
6059 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006060 }
6061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006062 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6063 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6064 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07006065 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 }
6067 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6068 mPersistentStartingProcesses.add(app);
6069 startProcessLocked(app, "added application", app.processName);
6070 }
6071
6072 return app;
6073 }
6074
6075 public void unhandledBack() {
6076 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6077 "unhandledBack()");
6078
6079 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006080 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006081 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006082 TAG, "Performing unhandledBack(): stack size = " + count);
6083 if (count > 1) {
6084 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006085 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006086 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6087 Binder.restoreCallingIdentity(origId);
6088 }
6089 }
6090 }
6091
6092 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6093 String name = uri.getAuthority();
6094 ContentProviderHolder cph = getContentProviderExternal(name);
6095 ParcelFileDescriptor pfd = null;
6096 if (cph != null) {
6097 // We record the binder invoker's uid in thread-local storage before
6098 // going to the content provider to open the file. Later, in the code
6099 // that handles all permissions checks, we look for this uid and use
6100 // that rather than the Activity Manager's own uid. The effect is that
6101 // we do the check against the caller's permissions even though it looks
6102 // to the content provider like the Activity Manager itself is making
6103 // the request.
6104 sCallerIdentity.set(new Identity(
6105 Binder.getCallingPid(), Binder.getCallingUid()));
6106 try {
6107 pfd = cph.provider.openFile(uri, "r");
6108 } catch (FileNotFoundException e) {
6109 // do nothing; pfd will be returned null
6110 } finally {
6111 // Ensure that whatever happens, we clean up the identity state
6112 sCallerIdentity.remove();
6113 }
6114
6115 // We've got the fd now, so we're done with the provider.
6116 removeContentProviderExternal(name);
6117 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006118 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006119 }
6120 return pfd;
6121 }
6122
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006123 // Actually is sleeping or shutting down or whatever else in the future
6124 // is an inactive state.
6125 public boolean isSleeping() {
6126 return mSleeping || mShuttingDown;
6127 }
6128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006129 public void goingToSleep() {
6130 synchronized(this) {
6131 mSleeping = true;
6132 mWindowManager.setEventDispatching(false);
6133
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006134 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006135
6136 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006137 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006138 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6139 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006140 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006141 }
6142 }
6143
Dianne Hackborn55280a92009-05-07 15:53:46 -07006144 public boolean shutdown(int timeout) {
6145 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6146 != PackageManager.PERMISSION_GRANTED) {
6147 throw new SecurityException("Requires permission "
6148 + android.Manifest.permission.SHUTDOWN);
6149 }
6150
6151 boolean timedout = false;
6152
6153 synchronized(this) {
6154 mShuttingDown = true;
6155 mWindowManager.setEventDispatching(false);
6156
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006157 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006158 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006159 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006160 while (mMainStack.mResumedActivity != null
6161 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006162 long delay = endTime - System.currentTimeMillis();
6163 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006164 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006165 timedout = true;
6166 break;
6167 }
6168 try {
6169 this.wait();
6170 } catch (InterruptedException e) {
6171 }
6172 }
6173 }
6174 }
6175
6176 mUsageStatsService.shutdown();
6177 mBatteryStatsService.shutdown();
6178
6179 return timedout;
6180 }
6181
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006182 public final void activitySlept(IBinder token) {
6183 if (localLOGV) Slog.v(
6184 TAG, "Activity slept: token=" + token);
6185
6186 ActivityRecord r = null;
6187
6188 final long origId = Binder.clearCallingIdentity();
6189
6190 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006191 r = mMainStack.isInStackLocked(token);
6192 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006193 mMainStack.activitySleptLocked(r);
6194 }
6195 }
6196
6197 Binder.restoreCallingIdentity(origId);
6198 }
6199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006200 public void wakingUp() {
6201 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006202 mWindowManager.setEventDispatching(true);
6203 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006204 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006205 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006206 }
6207 }
6208
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006209 public void stopAppSwitches() {
6210 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6211 != PackageManager.PERMISSION_GRANTED) {
6212 throw new SecurityException("Requires permission "
6213 + android.Manifest.permission.STOP_APP_SWITCHES);
6214 }
6215
6216 synchronized(this) {
6217 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6218 + APP_SWITCH_DELAY_TIME;
6219 mDidAppSwitch = false;
6220 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6221 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6222 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6223 }
6224 }
6225
6226 public void resumeAppSwitches() {
6227 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6228 != PackageManager.PERMISSION_GRANTED) {
6229 throw new SecurityException("Requires permission "
6230 + android.Manifest.permission.STOP_APP_SWITCHES);
6231 }
6232
6233 synchronized(this) {
6234 // Note that we don't execute any pending app switches... we will
6235 // let those wait until either the timeout, or the next start
6236 // activity request.
6237 mAppSwitchesAllowedTime = 0;
6238 }
6239 }
6240
6241 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6242 String name) {
6243 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6244 return true;
6245 }
6246
6247 final int perm = checkComponentPermission(
6248 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006249 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006250 if (perm == PackageManager.PERMISSION_GRANTED) {
6251 return true;
6252 }
6253
Joe Onorato8a9b2202010-02-26 18:56:32 -08006254 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006255 return false;
6256 }
6257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006258 public void setDebugApp(String packageName, boolean waitForDebugger,
6259 boolean persistent) {
6260 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6261 "setDebugApp()");
6262
6263 // Note that this is not really thread safe if there are multiple
6264 // callers into it at the same time, but that's not a situation we
6265 // care about.
6266 if (persistent) {
6267 final ContentResolver resolver = mContext.getContentResolver();
6268 Settings.System.putString(
6269 resolver, Settings.System.DEBUG_APP,
6270 packageName);
6271 Settings.System.putInt(
6272 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6273 waitForDebugger ? 1 : 0);
6274 }
6275
6276 synchronized (this) {
6277 if (!persistent) {
6278 mOrigDebugApp = mDebugApp;
6279 mOrigWaitForDebugger = mWaitForDebugger;
6280 }
6281 mDebugApp = packageName;
6282 mWaitForDebugger = waitForDebugger;
6283 mDebugTransient = !persistent;
6284 if (packageName != null) {
6285 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006286 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006287 Binder.restoreCallingIdentity(origId);
6288 }
6289 }
6290 }
6291
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006292 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6293 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6294 synchronized (this) {
6295 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6296 if (!isDebuggable) {
6297 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6298 throw new SecurityException("Process not debuggable: " + app.packageName);
6299 }
6300 }
6301 mProfileApp = processName;
6302 mProfileFile = profileFile;
6303 if (mProfileFd != null) {
6304 try {
6305 mProfileFd.close();
6306 } catch (IOException e) {
6307 }
6308 mProfileFd = null;
6309 }
6310 mProfileFd = profileFd;
6311 mProfileType = 0;
6312 mAutoStopProfiler = autoStopProfiler;
6313 }
6314 }
6315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006316 public void setAlwaysFinish(boolean enabled) {
6317 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6318 "setAlwaysFinish()");
6319
6320 Settings.System.putInt(
6321 mContext.getContentResolver(),
6322 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6323
6324 synchronized (this) {
6325 mAlwaysFinishActivities = enabled;
6326 }
6327 }
6328
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006329 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006330 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006331 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006332 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006333 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006334 }
6335 }
6336
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006337 public boolean isUserAMonkey() {
6338 // For now the fact that there is a controller implies
6339 // we have a monkey.
6340 synchronized (this) {
6341 return mController != null;
6342 }
6343 }
6344
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006345 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006346 synchronized (this) {
6347 mWatchers.register(watcher);
6348 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006349 }
6350
6351 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006352 synchronized (this) {
6353 mWatchers.unregister(watcher);
6354 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006355 }
6356
Jeff Sharkeya4620792011-05-20 15:29:23 -07006357 public void registerProcessObserver(IProcessObserver observer) {
6358 mProcessObservers.register(observer);
6359 }
6360
6361 public void unregisterProcessObserver(IProcessObserver observer) {
6362 mProcessObservers.unregister(observer);
6363 }
6364
Daniel Sandler69a48172010-06-23 16:29:36 -04006365 public void setImmersive(IBinder token, boolean immersive) {
6366 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006367 ActivityRecord r = mMainStack.isInStackLocked(token);
6368 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006369 throw new IllegalArgumentException();
6370 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006371 r.immersive = immersive;
6372 }
6373 }
6374
6375 public boolean isImmersive(IBinder token) {
6376 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006377 ActivityRecord r = mMainStack.isInStackLocked(token);
6378 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006379 throw new IllegalArgumentException();
6380 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006381 return r.immersive;
6382 }
6383 }
6384
6385 public boolean isTopActivityImmersive() {
6386 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006387 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006388 return (r != null) ? r.immersive : false;
6389 }
6390 }
6391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006392 public final void enterSafeMode() {
6393 synchronized(this) {
6394 // It only makes sense to do this before the system is ready
6395 // and started launching other packages.
6396 if (!mSystemReady) {
6397 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006398 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006399 } catch (RemoteException e) {
6400 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006401 }
6402 }
6403 }
6404
Jeff Brownb09abc12011-01-13 21:08:27 -08006405 public final void showSafeModeOverlay() {
6406 View v = LayoutInflater.from(mContext).inflate(
6407 com.android.internal.R.layout.safe_mode, null);
6408 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6409 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6410 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6411 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6412 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6413 lp.format = v.getBackground().getOpacity();
6414 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6415 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6416 ((WindowManager)mContext.getSystemService(
6417 Context.WINDOW_SERVICE)).addView(v, lp);
6418 }
6419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006420 public void noteWakeupAlarm(IIntentSender sender) {
6421 if (!(sender instanceof PendingIntentRecord)) {
6422 return;
6423 }
6424 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6425 synchronized (stats) {
6426 if (mBatteryStatsService.isOnBattery()) {
6427 mBatteryStatsService.enforceCallingPermission();
6428 PendingIntentRecord rec = (PendingIntentRecord)sender;
6429 int MY_UID = Binder.getCallingUid();
6430 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6431 BatteryStatsImpl.Uid.Pkg pkg =
6432 stats.getPackageStatsLocked(uid, rec.key.packageName);
6433 pkg.incWakeupsLocked();
6434 }
6435 }
6436 }
6437
Dianne Hackborn64825172011-03-02 21:32:58 -08006438 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006439 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006440 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006441 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006442 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006443 // XXX Note: don't acquire main activity lock here, because the window
6444 // manager calls in with its locks held.
6445
6446 boolean killed = false;
6447 synchronized (mPidsSelfLocked) {
6448 int[] types = new int[pids.length];
6449 int worstType = 0;
6450 for (int i=0; i<pids.length; i++) {
6451 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6452 if (proc != null) {
6453 int type = proc.setAdj;
6454 types[i] = type;
6455 if (type > worstType) {
6456 worstType = type;
6457 }
6458 }
6459 }
6460
Dianne Hackborn64825172011-03-02 21:32:58 -08006461 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006462 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006463 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6464 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006465 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006466
6467 // If this is not a secure call, don't let it kill processes that
6468 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006469 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6470 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006471 }
6472
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006473 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006474 for (int i=0; i<pids.length; i++) {
6475 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6476 if (proc == null) {
6477 continue;
6478 }
6479 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006480 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006481 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006482 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6483 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006484 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006485 proc.killedBackground = true;
6486 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006487 }
6488 }
6489 }
6490 return killed;
6491 }
6492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006493 public final void startRunning(String pkg, String cls, String action,
6494 String data) {
6495 synchronized(this) {
6496 if (mStartRunning) {
6497 return;
6498 }
6499 mStartRunning = true;
6500 mTopComponent = pkg != null && cls != null
6501 ? new ComponentName(pkg, cls) : null;
6502 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6503 mTopData = data;
6504 if (!mSystemReady) {
6505 return;
6506 }
6507 }
6508
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006509 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006510 }
6511
6512 private void retrieveSettings() {
6513 final ContentResolver resolver = mContext.getContentResolver();
6514 String debugApp = Settings.System.getString(
6515 resolver, Settings.System.DEBUG_APP);
6516 boolean waitForDebugger = Settings.System.getInt(
6517 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6518 boolean alwaysFinishActivities = Settings.System.getInt(
6519 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6520
6521 Configuration configuration = new Configuration();
6522 Settings.System.getConfiguration(resolver, configuration);
6523
6524 synchronized (this) {
6525 mDebugApp = mOrigDebugApp = debugApp;
6526 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6527 mAlwaysFinishActivities = alwaysFinishActivities;
6528 // This happens before any activities are started, so we can
6529 // change mConfiguration in-place.
6530 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006531 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006532 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006533 }
6534 }
6535
6536 public boolean testIsSystemReady() {
6537 // no need to synchronize(this) just to read & return the value
6538 return mSystemReady;
6539 }
6540
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006541 private static File getCalledPreBootReceiversFile() {
6542 File dataDir = Environment.getDataDirectory();
6543 File systemDir = new File(dataDir, "system");
6544 File fname = new File(systemDir, "called_pre_boots.dat");
6545 return fname;
6546 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006547
6548 static final int LAST_DONE_VERSION = 10000;
6549
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006550 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6551 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6552 File file = getCalledPreBootReceiversFile();
6553 FileInputStream fis = null;
6554 try {
6555 fis = new FileInputStream(file);
6556 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006557 int fvers = dis.readInt();
6558 if (fvers == LAST_DONE_VERSION) {
6559 String vers = dis.readUTF();
6560 String codename = dis.readUTF();
6561 String build = dis.readUTF();
6562 if (android.os.Build.VERSION.RELEASE.equals(vers)
6563 && android.os.Build.VERSION.CODENAME.equals(codename)
6564 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6565 int num = dis.readInt();
6566 while (num > 0) {
6567 num--;
6568 String pkg = dis.readUTF();
6569 String cls = dis.readUTF();
6570 lastDoneReceivers.add(new ComponentName(pkg, cls));
6571 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006572 }
6573 }
6574 } catch (FileNotFoundException e) {
6575 } catch (IOException e) {
6576 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6577 } finally {
6578 if (fis != null) {
6579 try {
6580 fis.close();
6581 } catch (IOException e) {
6582 }
6583 }
6584 }
6585 return lastDoneReceivers;
6586 }
6587
6588 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6589 File file = getCalledPreBootReceiversFile();
6590 FileOutputStream fos = null;
6591 DataOutputStream dos = null;
6592 try {
6593 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6594 fos = new FileOutputStream(file);
6595 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006596 dos.writeInt(LAST_DONE_VERSION);
6597 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006598 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006599 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006600 dos.writeInt(list.size());
6601 for (int i=0; i<list.size(); i++) {
6602 dos.writeUTF(list.get(i).getPackageName());
6603 dos.writeUTF(list.get(i).getClassName());
6604 }
6605 } catch (IOException e) {
6606 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6607 file.delete();
6608 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006609 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006610 if (dos != null) {
6611 try {
6612 dos.close();
6613 } catch (IOException e) {
6614 // TODO Auto-generated catch block
6615 e.printStackTrace();
6616 }
6617 }
6618 }
6619 }
6620
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006621 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006622 synchronized(this) {
6623 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006624 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006625 return;
6626 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006627
6628 // Check to see if there are any update receivers to run.
6629 if (!mDidUpdate) {
6630 if (mWaitingUpdate) {
6631 return;
6632 }
6633 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6634 List<ResolveInfo> ris = null;
6635 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006636 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006637 intent, null, 0);
6638 } catch (RemoteException e) {
6639 }
6640 if (ris != null) {
6641 for (int i=ris.size()-1; i>=0; i--) {
6642 if ((ris.get(i).activityInfo.applicationInfo.flags
6643 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6644 ris.remove(i);
6645 }
6646 }
6647 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006648
6649 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6650
6651 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006652 for (int i=0; i<ris.size(); i++) {
6653 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006654 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6655 if (lastDoneReceivers.contains(comp)) {
6656 ris.remove(i);
6657 i--;
6658 }
6659 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006660
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006661 for (int i=0; i<ris.size(); i++) {
6662 ActivityInfo ai = ris.get(i).activityInfo;
6663 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6664 doneReceivers.add(comp);
6665 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006666 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006667 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006668 finisher = new IIntentReceiver.Stub() {
6669 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006670 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006671 boolean sticky) {
6672 // The raw IIntentReceiver interface is called
6673 // with the AM lock held, so redispatch to
6674 // execute our code without the lock.
6675 mHandler.post(new Runnable() {
6676 public void run() {
6677 synchronized (ActivityManagerService.this) {
6678 mDidUpdate = true;
6679 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006680 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006681 showBootMessage(mContext.getText(
6682 R.string.android_upgrading_complete),
6683 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006684 systemReady(goingCallback);
6685 }
6686 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006687 }
6688 };
6689 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006690 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006691 broadcastIntentLocked(null, null, intent, null, finisher,
6692 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006693 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006694 mWaitingUpdate = true;
6695 }
6696 }
6697 }
6698 if (mWaitingUpdate) {
6699 return;
6700 }
6701 mDidUpdate = true;
6702 }
6703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006704 mSystemReady = true;
6705 if (!mStartRunning) {
6706 return;
6707 }
6708 }
6709
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006710 ArrayList<ProcessRecord> procsToKill = null;
6711 synchronized(mPidsSelfLocked) {
6712 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6713 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6714 if (!isAllowedWhileBooting(proc.info)){
6715 if (procsToKill == null) {
6716 procsToKill = new ArrayList<ProcessRecord>();
6717 }
6718 procsToKill.add(proc);
6719 }
6720 }
6721 }
6722
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006723 synchronized(this) {
6724 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006725 for (int i=procsToKill.size()-1; i>=0; i--) {
6726 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006727 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006728 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006729 }
6730 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006731
6732 // Now that we have cleaned up any update processes, we
6733 // are ready to start launching real processes and know that
6734 // we won't trample on them any more.
6735 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006736 }
6737
Joe Onorato8a9b2202010-02-26 18:56:32 -08006738 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006739 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006740 SystemClock.uptimeMillis());
6741
6742 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006743 // Make sure we have no pre-ready processes sitting around.
6744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006745 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6746 ResolveInfo ri = mContext.getPackageManager()
6747 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006748 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006749 CharSequence errorMsg = null;
6750 if (ri != null) {
6751 ActivityInfo ai = ri.activityInfo;
6752 ApplicationInfo app = ai.applicationInfo;
6753 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6754 mTopAction = Intent.ACTION_FACTORY_TEST;
6755 mTopData = null;
6756 mTopComponent = new ComponentName(app.packageName,
6757 ai.name);
6758 } else {
6759 errorMsg = mContext.getResources().getText(
6760 com.android.internal.R.string.factorytest_not_system);
6761 }
6762 } else {
6763 errorMsg = mContext.getResources().getText(
6764 com.android.internal.R.string.factorytest_no_action);
6765 }
6766 if (errorMsg != null) {
6767 mTopAction = null;
6768 mTopData = null;
6769 mTopComponent = null;
6770 Message msg = Message.obtain();
6771 msg.what = SHOW_FACTORY_ERROR_MSG;
6772 msg.getData().putCharSequence("msg", errorMsg);
6773 mHandler.sendMessage(msg);
6774 }
6775 }
6776 }
6777
6778 retrieveSettings();
6779
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006780 if (goingCallback != null) goingCallback.run();
6781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006782 synchronized (this) {
6783 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6784 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006785 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006786 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006787 if (apps != null) {
6788 int N = apps.size();
6789 int i;
6790 for (i=0; i<N; i++) {
6791 ApplicationInfo info
6792 = (ApplicationInfo)apps.get(i);
6793 if (info != null &&
6794 !info.packageName.equals("android")) {
6795 addAppLocked(info);
6796 }
6797 }
6798 }
6799 } catch (RemoteException ex) {
6800 // pm is in same process, this will never happen.
6801 }
6802 }
6803
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006804 // Start up initial activity.
6805 mBooting = true;
6806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006807 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006808 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006809 Message msg = Message.obtain();
6810 msg.what = SHOW_UID_ERROR_MSG;
6811 mHandler.sendMessage(msg);
6812 }
6813 } catch (RemoteException e) {
6814 }
6815
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006816 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006817 }
6818 }
6819
Dan Egnorb7f03672009-12-09 16:22:32 -08006820 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006821 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006822 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006823 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006824 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006825 startAppProblemLocked(app);
6826 app.stopFreezingAllLocked();
6827 return handleAppCrashLocked(app);
6828 }
6829
Dan Egnorb7f03672009-12-09 16:22:32 -08006830 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006831 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006832 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006833 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006834 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6835 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006836 startAppProblemLocked(app);
6837 app.stopFreezingAllLocked();
6838 }
6839
6840 /**
6841 * Generate a process error record, suitable for attachment to a ProcessRecord.
6842 *
6843 * @param app The ProcessRecord in which the error occurred.
6844 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6845 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006846 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006847 * @param shortMsg Short message describing the crash.
6848 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006849 * @param stackTrace Full crash stack trace, may be null.
6850 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006851 * @return Returns a fully-formed AppErrorStateInfo record.
6852 */
6853 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006854 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006855 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006857 report.condition = condition;
6858 report.processName = app.processName;
6859 report.pid = app.pid;
6860 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006861 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006862 report.shortMsg = shortMsg;
6863 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006864 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006865
6866 return report;
6867 }
6868
Dan Egnor42471dd2010-01-07 17:25:22 -08006869 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006870 synchronized (this) {
6871 app.crashing = false;
6872 app.crashingReport = null;
6873 app.notResponding = false;
6874 app.notRespondingReport = null;
6875 if (app.anrDialog == fromDialog) {
6876 app.anrDialog = null;
6877 }
6878 if (app.waitDialog == fromDialog) {
6879 app.waitDialog = null;
6880 }
6881 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006882 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006883 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006884 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6885 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006886 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006887 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006888 }
6889 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006890
Dan Egnorb7f03672009-12-09 16:22:32 -08006891 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006892 long now = SystemClock.uptimeMillis();
6893
6894 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6895 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006896 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006897 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006898 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006899 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006900 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006901 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006902 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6903 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006904 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006905 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006906 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006907 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006908 }
6909 }
6910 if (!app.persistent) {
6911 // We don't want to start this process again until the user
6912 // explicitly does so... but for persistent process, we really
6913 // need to keep it running. If a persistent process is actually
6914 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006915 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006916 app.info.processName);
6917 mBadProcesses.put(app.info.processName, app.info.uid, now);
6918 app.bad = true;
6919 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6920 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006921 // Don't let services in this process be restarted and potentially
6922 // annoy the user repeatedly. Unless it is persistent, since those
6923 // processes run critical code.
6924 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006925 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006926 return false;
6927 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006928 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006929 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006930 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006931 if (r.app == app) {
6932 // If the top running activity is from this crashing
6933 // process, then terminate it to avoid getting in a loop.
6934 Slog.w(TAG, " Force finishing activity "
6935 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006936 int index = mMainStack.indexOfTokenLocked(r);
6937 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006938 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006939 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006940 // stopped, to avoid a situation where one will get
6941 // re-start our crashing activity once it gets resumed again.
6942 index--;
6943 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006944 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006945 if (r.state == ActivityState.RESUMED
6946 || r.state == ActivityState.PAUSING
6947 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006948 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006949 Slog.w(TAG, " Force finishing activity "
6950 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006951 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006952 Activity.RESULT_CANCELED, null, "crashed");
6953 }
6954 }
6955 }
6956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957 }
6958
6959 // Bump up the crash count of any services currently running in the proc.
6960 if (app.services.size() != 0) {
6961 // Any services running in the application need to be placed
6962 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006963 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006964 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006965 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006966 sr.crashCount++;
6967 }
6968 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006969
6970 // If the crashing process is what we consider to be the "home process" and it has been
6971 // replaced by a third-party app, clear the package preferred activities from packages
6972 // with a home activity running in the process to prevent a repeatedly crashing app
6973 // from blocking the user to manually clear the list.
6974 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6975 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6976 Iterator it = mHomeProcess.activities.iterator();
6977 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006978 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006979 if (r.isHomeActivity) {
6980 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6981 try {
6982 ActivityThread.getPackageManager()
6983 .clearPackagePreferredActivities(r.packageName);
6984 } catch (RemoteException c) {
6985 // pm is in same process, this will never happen.
6986 }
6987 }
6988 }
6989 }
6990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006991 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6992 return true;
6993 }
6994
6995 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006996 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6997 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006998 skipCurrentReceiverLocked(app);
6999 }
7000
7001 void skipCurrentReceiverLocked(ProcessRecord app) {
7002 boolean reschedule = false;
7003 BroadcastRecord r = app.curReceiver;
7004 if (r != null) {
7005 // The current broadcast is waiting for this app's receiver
7006 // to be finished. Looks like that's not going to happen, so
7007 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007008 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007009 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7010 r.resultExtras, r.resultAbort, true);
7011 reschedule = true;
7012 }
7013 r = mPendingBroadcast;
7014 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007015 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007016 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007017 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7019 r.resultExtras, r.resultAbort, true);
7020 reschedule = true;
7021 }
7022 if (reschedule) {
7023 scheduleBroadcastsLocked();
7024 }
7025 }
7026
Dan Egnor60d87622009-12-16 16:32:58 -08007027 /**
7028 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7029 * The application process will exit immediately after this call returns.
7030 * @param app object of the crashing app, null for the system server
7031 * @param crashInfo describing the exception
7032 */
7033 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007034 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08007035
7036 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7037 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007038 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007039 crashInfo.exceptionClassName,
7040 crashInfo.exceptionMessage,
7041 crashInfo.throwFileName,
7042 crashInfo.throwLineNumber);
7043
Dan Egnor42471dd2010-01-07 17:25:22 -08007044 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007045
7046 crashApplication(r, crashInfo);
7047 }
7048
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007049 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007050 IBinder app,
7051 int violationMask,
7052 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007053 ProcessRecord r = findAppProcess(app, "StrictMode");
7054 if (r == null) {
7055 return;
7056 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007057
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007058 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007059 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007060 boolean logIt = true;
7061 synchronized (mAlreadyLoggedViolatedStacks) {
7062 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7063 logIt = false;
7064 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007065 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007066 // the relative pain numbers, without logging all
7067 // the stack traces repeatedly. We'd want to do
7068 // likewise in the client code, which also does
7069 // dup suppression, before the Binder call.
7070 } else {
7071 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7072 mAlreadyLoggedViolatedStacks.clear();
7073 }
7074 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7075 }
7076 }
7077 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007078 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007079 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007080 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007081
7082 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7083 AppErrorResult result = new AppErrorResult();
7084 synchronized (this) {
7085 final long origId = Binder.clearCallingIdentity();
7086
7087 Message msg = Message.obtain();
7088 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7089 HashMap<String, Object> data = new HashMap<String, Object>();
7090 data.put("result", result);
7091 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007092 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007093 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007094 msg.obj = data;
7095 mHandler.sendMessage(msg);
7096
7097 Binder.restoreCallingIdentity(origId);
7098 }
7099 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007100 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007101 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007102 }
7103
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007104 // Depending on the policy in effect, there could be a bunch of
7105 // these in quick succession so we try to batch these together to
7106 // minimize disk writes, number of dropbox entries, and maximize
7107 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007108 private void logStrictModeViolationToDropBox(
7109 ProcessRecord process,
7110 StrictMode.ViolationInfo info) {
7111 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007112 return;
7113 }
7114 final boolean isSystemApp = process == null ||
7115 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7116 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7117 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7118 final DropBoxManager dbox = (DropBoxManager)
7119 mContext.getSystemService(Context.DROPBOX_SERVICE);
7120
7121 // Exit early if the dropbox isn't configured to accept this report type.
7122 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7123
7124 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007125 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007126 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7127 synchronized (sb) {
7128 bufferWasEmpty = sb.length() == 0;
7129 appendDropBoxProcessHeaders(process, sb);
7130 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7131 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007132 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7133 if (info.violationNumThisLoop != 0) {
7134 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7135 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007136 if (info.numAnimationsRunning != 0) {
7137 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7138 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007139 if (info.broadcastIntentAction != null) {
7140 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7141 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007142 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007143 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007144 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007145 if (info.numInstances != -1) {
7146 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7147 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007148 if (info.tags != null) {
7149 for (String tag : info.tags) {
7150 sb.append("Span-Tag: ").append(tag).append("\n");
7151 }
7152 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007153 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007154 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7155 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007156 }
7157 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007158
7159 // Only buffer up to ~64k. Various logging bits truncate
7160 // things at 128k.
7161 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007162 }
7163
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007164 // Flush immediately if the buffer's grown too large, or this
7165 // is a non-system app. Non-system apps are isolated with a
7166 // different tag & policy and not batched.
7167 //
7168 // Batching is useful during internal testing with
7169 // StrictMode settings turned up high. Without batching,
7170 // thousands of separate files could be created on boot.
7171 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007172 new Thread("Error dump: " + dropboxTag) {
7173 @Override
7174 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007175 String report;
7176 synchronized (sb) {
7177 report = sb.toString();
7178 sb.delete(0, sb.length());
7179 sb.trimToSize();
7180 }
7181 if (report.length() != 0) {
7182 dbox.addText(dropboxTag, report);
7183 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007184 }
7185 }.start();
7186 return;
7187 }
7188
7189 // System app batching:
7190 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007191 // An existing dropbox-writing thread is outstanding, so
7192 // we don't need to start it up. The existing thread will
7193 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007194 return;
7195 }
7196
7197 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7198 // (After this point, we shouldn't access AMS internal data structures.)
7199 new Thread("Error dump: " + dropboxTag) {
7200 @Override
7201 public void run() {
7202 // 5 second sleep to let stacks arrive and be batched together
7203 try {
7204 Thread.sleep(5000); // 5 seconds
7205 } catch (InterruptedException e) {}
7206
7207 String errorReport;
7208 synchronized (mStrictModeBuffer) {
7209 errorReport = mStrictModeBuffer.toString();
7210 if (errorReport.length() == 0) {
7211 return;
7212 }
7213 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7214 mStrictModeBuffer.trimToSize();
7215 }
7216 dbox.addText(dropboxTag, errorReport);
7217 }
7218 }.start();
7219 }
7220
Dan Egnor60d87622009-12-16 16:32:58 -08007221 /**
7222 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7223 * @param app object of the crashing app, null for the system server
7224 * @param tag reported by the caller
7225 * @param crashInfo describing the context of the error
7226 * @return true if the process should exit immediately (WTF is fatal)
7227 */
7228 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007229 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007230 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007231
7232 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7233 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007234 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007235 tag, crashInfo.exceptionMessage);
7236
Dan Egnor42471dd2010-01-07 17:25:22 -08007237 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007238
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007239 if (r != null && r.pid != Process.myPid() &&
7240 Settings.Secure.getInt(mContext.getContentResolver(),
7241 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007242 crashApplication(r, crashInfo);
7243 return true;
7244 } else {
7245 return false;
7246 }
7247 }
7248
7249 /**
7250 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7251 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7252 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007253 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007254 if (app == null) {
7255 return null;
7256 }
7257
7258 synchronized (this) {
7259 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7260 final int NA = apps.size();
7261 for (int ia=0; ia<NA; ia++) {
7262 ProcessRecord p = apps.valueAt(ia);
7263 if (p.thread != null && p.thread.asBinder() == app) {
7264 return p;
7265 }
7266 }
7267 }
7268
Dianne Hackborncb44d962011-03-10 17:02:27 -08007269 Slog.w(TAG, "Can't find mystery application for " + reason
7270 + " from pid=" + Binder.getCallingPid()
7271 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007272 return null;
7273 }
7274 }
7275
7276 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007277 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7278 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007279 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007280 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007281 // Watchdog thread ends up invoking this function (with
7282 // a null ProcessRecord) to add the stack file to dropbox.
7283 // Do not acquire a lock on this (am) in such cases, as it
7284 // could cause a potential deadlock, if and when watchdog
7285 // is invoked due to unavailability of lock on am and it
7286 // would prevent watchdog from killing system_server.
7287 if (process == null) {
7288 sb.append("Process: system_server\n");
7289 return;
7290 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007291 // Note: ProcessRecord 'process' is guarded by the service
7292 // instance. (notably process.pkgList, which could otherwise change
7293 // concurrently during execution of this method)
7294 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007295 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007296 sb.append("Process: system_server\n");
7297 } else {
7298 sb.append("Process: ").append(process.processName).append("\n");
7299 }
Dan Egnora455d192010-03-12 08:52:28 -08007300 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007301 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007302 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7303 for (String pkg : process.pkgList) {
7304 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007305 try {
Dan Egnora455d192010-03-12 08:52:28 -08007306 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7307 if (pi != null) {
7308 sb.append(" v").append(pi.versionCode);
7309 if (pi.versionName != null) {
7310 sb.append(" (").append(pi.versionName).append(")");
7311 }
7312 }
7313 } catch (RemoteException e) {
7314 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007315 }
Dan Egnora455d192010-03-12 08:52:28 -08007316 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007317 }
Dan Egnora455d192010-03-12 08:52:28 -08007318 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007319 }
7320
7321 private static String processClass(ProcessRecord process) {
7322 if (process == null || process.pid == MY_PID) {
7323 return "system_server";
7324 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7325 return "system_app";
7326 } else {
7327 return "data_app";
7328 }
7329 }
7330
7331 /**
7332 * Write a description of an error (crash, WTF, ANR) to the drop box.
7333 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7334 * @param process which caused the error, null means the system server
7335 * @param activity which triggered the error, null if unknown
7336 * @param parent activity related to the error, null if unknown
7337 * @param subject line related to the error, null if absent
7338 * @param report in long form describing the error, null if absent
7339 * @param logFile to include in the report, null if none
7340 * @param crashInfo giving an application stack trace, null if absent
7341 */
7342 public void addErrorToDropBox(String eventType,
7343 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7344 final String report, final File logFile,
7345 final ApplicationErrorReport.CrashInfo crashInfo) {
7346 // NOTE -- this must never acquire the ActivityManagerService lock,
7347 // otherwise the watchdog may be prevented from resetting the system.
7348
7349 final String dropboxTag = processClass(process) + "_" + eventType;
7350 final DropBoxManager dbox = (DropBoxManager)
7351 mContext.getSystemService(Context.DROPBOX_SERVICE);
7352
7353 // Exit early if the dropbox isn't configured to accept this report type.
7354 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7355
7356 final StringBuilder sb = new StringBuilder(1024);
7357 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007358 if (activity != null) {
7359 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7360 }
7361 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7362 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7363 }
7364 if (parent != null && parent != activity) {
7365 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7366 }
7367 if (subject != null) {
7368 sb.append("Subject: ").append(subject).append("\n");
7369 }
7370 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007371 if (Debug.isDebuggerConnected()) {
7372 sb.append("Debugger: Connected\n");
7373 }
Dan Egnora455d192010-03-12 08:52:28 -08007374 sb.append("\n");
7375
7376 // Do the rest in a worker thread to avoid blocking the caller on I/O
7377 // (After this point, we shouldn't access AMS internal data structures.)
7378 Thread worker = new Thread("Error dump: " + dropboxTag) {
7379 @Override
7380 public void run() {
7381 if (report != null) {
7382 sb.append(report);
7383 }
7384 if (logFile != null) {
7385 try {
7386 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7387 } catch (IOException e) {
7388 Slog.e(TAG, "Error reading " + logFile, e);
7389 }
7390 }
7391 if (crashInfo != null && crashInfo.stackTrace != null) {
7392 sb.append(crashInfo.stackTrace);
7393 }
7394
7395 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7396 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7397 if (lines > 0) {
7398 sb.append("\n");
7399
7400 // Merge several logcat streams, and take the last N lines
7401 InputStreamReader input = null;
7402 try {
7403 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7404 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7405 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7406
7407 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7408 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7409 input = new InputStreamReader(logcat.getInputStream());
7410
7411 int num;
7412 char[] buf = new char[8192];
7413 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7414 } catch (IOException e) {
7415 Slog.e(TAG, "Error running logcat", e);
7416 } finally {
7417 if (input != null) try { input.close(); } catch (IOException e) {}
7418 }
7419 }
7420
7421 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007422 }
Dan Egnora455d192010-03-12 08:52:28 -08007423 };
7424
7425 if (process == null || process.pid == MY_PID) {
7426 worker.run(); // We may be about to die -- need to run this synchronously
7427 } else {
7428 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007429 }
7430 }
7431
7432 /**
7433 * Bring up the "unexpected error" dialog box for a crashing app.
7434 * Deal with edge cases (intercepts from instrumented applications,
7435 * ActivityController, error intent receivers, that sort of thing).
7436 * @param r the application crashing
7437 * @param crashInfo describing the failure
7438 */
7439 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007440 long timeMillis = System.currentTimeMillis();
7441 String shortMsg = crashInfo.exceptionClassName;
7442 String longMsg = crashInfo.exceptionMessage;
7443 String stackTrace = crashInfo.stackTrace;
7444 if (shortMsg != null && longMsg != null) {
7445 longMsg = shortMsg + ": " + longMsg;
7446 } else if (shortMsg != null) {
7447 longMsg = shortMsg;
7448 }
7449
Dan Egnor60d87622009-12-16 16:32:58 -08007450 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007451 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007452 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007453 try {
7454 String name = r != null ? r.processName : null;
7455 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007456 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007457 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007458 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007459 + " at watcher's request");
7460 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007461 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007462 }
7463 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007464 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007465 }
7466 }
7467
7468 final long origId = Binder.clearCallingIdentity();
7469
7470 // If this process is running instrumentation, finish it.
7471 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007472 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007473 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007474 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7475 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007476 Bundle info = new Bundle();
7477 info.putString("shortMsg", shortMsg);
7478 info.putString("longMsg", longMsg);
7479 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7480 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007481 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007482 }
7483
Dan Egnor60d87622009-12-16 16:32:58 -08007484 // If we can't identify the process or it's already exceeded its crash quota,
7485 // quit right away without showing a crash dialog.
7486 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007487 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007488 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007489 }
7490
7491 Message msg = Message.obtain();
7492 msg.what = SHOW_ERROR_MSG;
7493 HashMap data = new HashMap();
7494 data.put("result", result);
7495 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007496 msg.obj = data;
7497 mHandler.sendMessage(msg);
7498
7499 Binder.restoreCallingIdentity(origId);
7500 }
7501
7502 int res = result.get();
7503
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007504 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007505 synchronized (this) {
7506 if (r != null) {
7507 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7508 SystemClock.uptimeMillis());
7509 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007510 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007511 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007512 }
7513 }
7514
7515 if (appErrorIntent != null) {
7516 try {
7517 mContext.startActivity(appErrorIntent);
7518 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007519 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007521 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007522 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007523
7524 Intent createAppErrorIntentLocked(ProcessRecord r,
7525 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7526 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007527 if (report == null) {
7528 return null;
7529 }
7530 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7531 result.setComponent(r.errorReportReceiver);
7532 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7533 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7534 return result;
7535 }
7536
Dan Egnorb7f03672009-12-09 16:22:32 -08007537 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7538 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007539 if (r.errorReportReceiver == null) {
7540 return null;
7541 }
7542
7543 if (!r.crashing && !r.notResponding) {
7544 return null;
7545 }
7546
Dan Egnorb7f03672009-12-09 16:22:32 -08007547 ApplicationErrorReport report = new ApplicationErrorReport();
7548 report.packageName = r.info.packageName;
7549 report.installerPackageName = r.errorReportReceiver.getPackageName();
7550 report.processName = r.processName;
7551 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007552 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007553
Dan Egnorb7f03672009-12-09 16:22:32 -08007554 if (r.crashing) {
7555 report.type = ApplicationErrorReport.TYPE_CRASH;
7556 report.crashInfo = crashInfo;
7557 } else if (r.notResponding) {
7558 report.type = ApplicationErrorReport.TYPE_ANR;
7559 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007560
Dan Egnorb7f03672009-12-09 16:22:32 -08007561 report.anrInfo.activity = r.notRespondingReport.tag;
7562 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7563 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007564 }
7565
Dan Egnorb7f03672009-12-09 16:22:32 -08007566 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007567 }
7568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007569 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7570 // assume our apps are happy - lazy create the list
7571 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7572
7573 synchronized (this) {
7574
7575 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007576 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7577 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007578 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7579 // This one's in trouble, so we'll generate a report for it
7580 // crashes are higher priority (in case there's a crash *and* an anr)
7581 ActivityManager.ProcessErrorStateInfo report = null;
7582 if (app.crashing) {
7583 report = app.crashingReport;
7584 } else if (app.notResponding) {
7585 report = app.notRespondingReport;
7586 }
7587
7588 if (report != null) {
7589 if (errList == null) {
7590 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7591 }
7592 errList.add(report);
7593 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007594 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007595 " crashing = " + app.crashing +
7596 " notResponding = " + app.notResponding);
7597 }
7598 }
7599 }
7600 }
7601
7602 return errList;
7603 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007604
7605 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
7606 if (adj >= ProcessList.EMPTY_APP_ADJ) {
7607 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7608 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
7609 if (currApp != null) {
7610 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7611 }
7612 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7613 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7614 if (currApp != null) {
7615 currApp.lru = 0;
7616 }
7617 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7618 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
7619 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7620 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7621 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7622 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7623 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7624 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7625 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7626 } else {
7627 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7628 }
7629 }
7630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007631 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7632 // Lazy instantiation of list
7633 List<ActivityManager.RunningAppProcessInfo> runList = null;
7634 synchronized (this) {
7635 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007636 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7637 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007638 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7639 // Generate process state info for running application
7640 ActivityManager.RunningAppProcessInfo currApp =
7641 new ActivityManager.RunningAppProcessInfo(app.processName,
7642 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007643 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007644 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007645 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007646 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007647 if (app.persistent) {
7648 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7649 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007650 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007651 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007652 currApp.importanceReasonCode = app.adjTypeCode;
7653 if (app.adjSource instanceof ProcessRecord) {
7654 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007655 currApp.importanceReasonImportance = oomAdjToImportance(
7656 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007657 } else if (app.adjSource instanceof ActivityRecord) {
7658 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007659 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7660 }
7661 if (app.adjTarget instanceof ComponentName) {
7662 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7663 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007664 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007665 // + " lru=" + currApp.lru);
7666 if (runList == null) {
7667 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7668 }
7669 runList.add(currApp);
7670 }
7671 }
7672 }
7673 return runList;
7674 }
7675
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007676 public List<ApplicationInfo> getRunningExternalApplications() {
7677 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7678 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7679 if (runningApps != null && runningApps.size() > 0) {
7680 Set<String> extList = new HashSet<String>();
7681 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7682 if (app.pkgList != null) {
7683 for (String pkg : app.pkgList) {
7684 extList.add(pkg);
7685 }
7686 }
7687 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007688 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007689 for (String pkg : extList) {
7690 try {
7691 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7692 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7693 retList.add(info);
7694 }
7695 } catch (RemoteException e) {
7696 }
7697 }
7698 }
7699 return retList;
7700 }
7701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007702 @Override
7703 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007704 if (checkCallingPermission(android.Manifest.permission.DUMP)
7705 != PackageManager.PERMISSION_GRANTED) {
7706 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7707 + Binder.getCallingPid()
7708 + ", uid=" + Binder.getCallingUid()
7709 + " without permission "
7710 + android.Manifest.permission.DUMP);
7711 return;
7712 }
7713
7714 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007715 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007716
7717 int opti = 0;
7718 while (opti < args.length) {
7719 String opt = args[opti];
7720 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7721 break;
7722 }
7723 opti++;
7724 if ("-a".equals(opt)) {
7725 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007726 } else if ("-c".equals(opt)) {
7727 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007728 } else if ("-h".equals(opt)) {
7729 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007730 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007731 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007732 pw.println(" a[ctivities]: activity stack state");
7733 pw.println(" b[roadcasts]: broadcast state");
7734 pw.println(" i[ntents]: pending intent state");
7735 pw.println(" p[rocesses]: process state");
7736 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007737 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7738 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007739 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007740 pw.println(" all: dump all activities");
7741 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007742 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007743 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7744 pw.println(" a partial substring in a component name, a");
7745 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007746 pw.println(" -a: include all available server state.");
7747 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007748 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007749 } else {
7750 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007751 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007752 }
7753
7754 // Is the caller requesting to dump a particular piece of data?
7755 if (opti < args.length) {
7756 String cmd = args[opti];
7757 opti++;
7758 if ("activities".equals(cmd) || "a".equals(cmd)) {
7759 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007760 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007761 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007762 return;
7763 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7764 synchronized (this) {
7765 dumpBroadcastsLocked(fd, pw, args, opti, true);
7766 }
7767 return;
7768 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7769 synchronized (this) {
7770 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7771 }
7772 return;
7773 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7774 synchronized (this) {
7775 dumpProcessesLocked(fd, pw, args, opti, true);
7776 }
7777 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007778 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7779 synchronized (this) {
7780 dumpOomLocked(fd, pw, args, opti, true);
7781 }
7782 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007783 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7784 synchronized (this) {
7785 dumpProvidersLocked(fd, pw, args, opti, true);
7786 }
7787 return;
7788 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007789 String[] newArgs;
7790 String name;
7791 if (opti >= args.length) {
7792 name = null;
7793 newArgs = EMPTY_STRING_ARRAY;
7794 } else {
7795 name = args[opti];
7796 opti++;
7797 newArgs = new String[args.length - opti];
7798 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7799 }
7800 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7801 pw.println("No services match: " + name);
7802 pw.println("Use -h for help.");
7803 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007804 return;
7805 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7806 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007807 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007808 }
7809 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007810 } else {
7811 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007812 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7813 pw.println("Bad activity command, or no activities match: " + cmd);
7814 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007815 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007816 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007817 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007818 }
7819
7820 // No piece of data specified, dump everything.
7821 synchronized (this) {
7822 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007823 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007824 if (needSep) {
7825 pw.println(" ");
7826 }
7827 if (dumpAll) {
7828 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007829 }
7830 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7831 if (needSep) {
7832 pw.println(" ");
7833 }
7834 if (dumpAll) {
7835 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007836 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007837 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007838 if (needSep) {
7839 pw.println(" ");
7840 }
7841 if (dumpAll) {
7842 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007843 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007844 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007845 if (needSep) {
7846 pw.println(" ");
7847 }
7848 if (dumpAll) {
7849 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007850 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007851 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007852 if (needSep) {
7853 pw.println(" ");
7854 }
7855 if (dumpAll) {
7856 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007857 }
7858 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7859 }
7860 }
7861
7862 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007863 int opti, boolean dumpAll, boolean dumpClient) {
7864 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7865 pw.println(" Main stack:");
7866 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007867 pw.println(" ");
7868 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007869 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007870 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007871 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007872 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007873 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7874 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007875 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007876 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007877 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007878 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007879 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7880 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007881 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007882 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7883 pw.println(" ");
7884 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007885 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7886 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007887 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007888 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007889 pw.println(" ");
7890 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007891 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7892 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007893 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007894
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007895 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007896 if (mMainStack.mPausingActivity != null) {
7897 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7898 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007899 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007900 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007901 if (dumpAll) {
7902 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7903 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007905
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007906 if (mRecentTasks.size() > 0) {
7907 pw.println();
7908 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007909
7910 final int N = mRecentTasks.size();
7911 for (int i=0; i<N; i++) {
7912 TaskRecord tr = mRecentTasks.get(i);
7913 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7914 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007915 if (dumpAll) {
7916 mRecentTasks.get(i).dump(pw, " ");
7917 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007918 }
7919 }
7920
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007921 if (dumpAll) {
7922 pw.println(" ");
7923 pw.println(" mCurTask: " + mCurTask);
7924 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007925
7926 return true;
7927 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007928
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007929 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7930 int opti, boolean dumpAll) {
7931 boolean needSep = false;
7932 int numPers = 0;
7933
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007934 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7935
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007936 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007937 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7938 final int NA = procs.size();
7939 for (int ia=0; ia<NA; ia++) {
7940 if (!needSep) {
7941 pw.println(" All known processes:");
7942 needSep = true;
7943 }
7944 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007945 pw.print(r.persistent ? " *PERS*" : " *APP*");
7946 pw.print(" UID "); pw.print(procs.keyAt(ia));
7947 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007948 r.dump(pw, " ");
7949 if (r.persistent) {
7950 numPers++;
7951 }
7952 }
7953 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007954 }
7955
7956 if (mLruProcesses.size() > 0) {
7957 if (needSep) pw.println(" ");
7958 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007959 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007960 dumpProcessOomList(pw, this, mLruProcesses, " ",
7961 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007962 needSep = true;
7963 }
7964
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007965 if (dumpAll) {
7966 synchronized (mPidsSelfLocked) {
7967 if (mPidsSelfLocked.size() > 0) {
7968 if (needSep) pw.println(" ");
7969 needSep = true;
7970 pw.println(" PID mappings:");
7971 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7972 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7973 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7974 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007975 }
7976 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007977 }
7978
7979 if (mForegroundProcesses.size() > 0) {
7980 if (needSep) pw.println(" ");
7981 needSep = true;
7982 pw.println(" Foreground Processes:");
7983 for (int i=0; i<mForegroundProcesses.size(); i++) {
7984 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7985 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007987 }
7988
7989 if (mPersistentStartingProcesses.size() > 0) {
7990 if (needSep) pw.println(" ");
7991 needSep = true;
7992 pw.println(" Persisent processes that are starting:");
7993 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007994 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007996
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007997 if (mRemovedProcesses.size() > 0) {
7998 if (needSep) pw.println(" ");
7999 needSep = true;
8000 pw.println(" Processes that are being removed:");
8001 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008002 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008003 }
8004
8005 if (mProcessesOnHold.size() > 0) {
8006 if (needSep) pw.println(" ");
8007 needSep = true;
8008 pw.println(" Processes that are on old until the system is ready:");
8009 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008010 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008011 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008012
Dianne Hackborn287952c2010-09-22 22:34:31 -07008013 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008014
8015 if (mProcessCrashTimes.getMap().size() > 0) {
8016 if (needSep) pw.println(" ");
8017 needSep = true;
8018 pw.println(" Time since processes crashed:");
8019 long now = SystemClock.uptimeMillis();
8020 for (Map.Entry<String, SparseArray<Long>> procs
8021 : mProcessCrashTimes.getMap().entrySet()) {
8022 SparseArray<Long> uids = procs.getValue();
8023 final int N = uids.size();
8024 for (int i=0; i<N; i++) {
8025 pw.print(" Process "); pw.print(procs.getKey());
8026 pw.print(" uid "); pw.print(uids.keyAt(i));
8027 pw.print(": last crashed ");
8028 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008029 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008030 }
8031 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008033
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008034 if (mBadProcesses.getMap().size() > 0) {
8035 if (needSep) pw.println(" ");
8036 needSep = true;
8037 pw.println(" Bad processes:");
8038 for (Map.Entry<String, SparseArray<Long>> procs
8039 : mBadProcesses.getMap().entrySet()) {
8040 SparseArray<Long> uids = procs.getValue();
8041 final int N = uids.size();
8042 for (int i=0; i<N; i++) {
8043 pw.print(" Bad process "); pw.print(procs.getKey());
8044 pw.print(" uid "); pw.print(uids.keyAt(i));
8045 pw.print(": crashed at time ");
8046 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008047 }
8048 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008049 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008050
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008051 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008052 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008053 if (mHeavyWeightProcess != null) {
8054 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8055 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008056 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008057 if (dumpAll) {
8058 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008059 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008060 pw.println(" mScreenCompatPackages:");
8061 for (Map.Entry<String, Integer> entry
8062 : mCompatModePackages.getPackages().entrySet()) {
8063 String pkg = entry.getKey();
8064 int mode = entry.getValue();
8065 pw.print(" "); pw.print(pkg); pw.print(": ");
8066 pw.print(mode); pw.println();
8067 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008068 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008069 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008070 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8071 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8072 || mOrigWaitForDebugger) {
8073 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8074 + " mDebugTransient=" + mDebugTransient
8075 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8076 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008077 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8078 || mProfileFd != null) {
8079 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8080 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8081 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8082 + mAutoStopProfiler);
8083 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008084 if (mAlwaysFinishActivities || mController != null) {
8085 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8086 + " mController=" + mController);
8087 }
8088 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008089 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008090 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008091 + " mProcessesReady=" + mProcessesReady
8092 + " mSystemReady=" + mSystemReady);
8093 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008094 + " mBooted=" + mBooted
8095 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008096 pw.print(" mLastPowerCheckRealtime=");
8097 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8098 pw.println("");
8099 pw.print(" mLastPowerCheckUptime=");
8100 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8101 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008102 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8103 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008104 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008105 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008106
8107 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008108 }
8109
Dianne Hackborn287952c2010-09-22 22:34:31 -07008110 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8111 int opti, boolean needSep, boolean dumpAll) {
8112 if (mProcessesToGc.size() > 0) {
8113 if (needSep) pw.println(" ");
8114 needSep = true;
8115 pw.println(" Processes that are waiting to GC:");
8116 long now = SystemClock.uptimeMillis();
8117 for (int i=0; i<mProcessesToGc.size(); i++) {
8118 ProcessRecord proc = mProcessesToGc.get(i);
8119 pw.print(" Process "); pw.println(proc);
8120 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8121 pw.print(", last gced=");
8122 pw.print(now-proc.lastRequestedGc);
8123 pw.print(" ms ago, last lowMem=");
8124 pw.print(now-proc.lastLowMemory);
8125 pw.println(" ms ago");
8126
8127 }
8128 }
8129 return needSep;
8130 }
8131
8132 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8133 int opti, boolean dumpAll) {
8134 boolean needSep = false;
8135
8136 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008137 if (needSep) pw.println(" ");
8138 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008139 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008140 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8141 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
8142 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8143 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8144 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8145 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8146 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8147 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
8148 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8149 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8150 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008151
8152 if (needSep) pw.println(" ");
8153 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008154 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008155 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008156 "Proc", "PERS", true);
8157 needSep = true;
8158 }
8159
8160 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8161
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008162 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008163 pw.println(" mHomeProcess: " + mHomeProcess);
8164 if (mHeavyWeightProcess != null) {
8165 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8166 }
8167
8168 return true;
8169 }
8170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008171 /**
8172 * There are three ways to call this:
8173 * - no service specified: dump all the services
8174 * - a flattened component name that matched an existing service was specified as the
8175 * first arg: dump that one service
8176 * - the first arg isn't the flattened component name of an existing service:
8177 * dump all services whose component contains the first arg as a substring
8178 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008179 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8180 int opti, boolean dumpAll) {
8181 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008182
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008183 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008184 synchronized (this) {
8185 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008186 services.add(r1);
8187 }
8188 }
8189 } else {
8190 ComponentName componentName = name != null
8191 ? ComponentName.unflattenFromString(name) : null;
8192 int objectId = 0;
8193 if (componentName == null) {
8194 // Not a '/' separated full component name; maybe an object ID?
8195 try {
8196 objectId = Integer.parseInt(name, 16);
8197 name = null;
8198 componentName = null;
8199 } catch (RuntimeException e) {
8200 }
8201 }
8202
8203 synchronized (this) {
8204 for (ServiceRecord r1 : mServices.values()) {
8205 if (componentName != null) {
8206 if (r1.name.equals(componentName)) {
8207 services.add(r1);
8208 }
8209 } else if (name != null) {
8210 if (r1.name.flattenToString().contains(name)) {
8211 services.add(r1);
8212 }
8213 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008214 services.add(r1);
8215 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008216 }
8217 }
8218 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008219
8220 if (services.size() <= 0) {
8221 return false;
8222 }
8223
8224 boolean needSep = false;
8225 for (int i=0; i<services.size(); i++) {
8226 if (needSep) {
8227 pw.println();
8228 }
8229 needSep = true;
8230 dumpService("", fd, pw, services.get(i), args, dumpAll);
8231 }
8232 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008233 }
8234
8235 /**
8236 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8237 * there is a thread associated with the service.
8238 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008239 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8240 final ServiceRecord r, String[] args, boolean dumpAll) {
8241 String innerPrefix = prefix + " ";
8242 synchronized (this) {
8243 pw.print(prefix); pw.print("SERVICE ");
8244 pw.print(r.shortName); pw.print(" ");
8245 pw.print(Integer.toHexString(System.identityHashCode(r)));
8246 pw.print(" pid=");
8247 if (r.app != null) pw.println(r.app.pid);
8248 else pw.println("(not running)");
8249 if (dumpAll) {
8250 r.dump(pw, innerPrefix);
8251 }
8252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008253 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008254 pw.print(prefix); pw.println(" Client:");
8255 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008256 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008257 TransferPipe tp = new TransferPipe();
8258 try {
8259 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8260 tp.setBufferPrefix(prefix + " ");
8261 tp.go(fd);
8262 } finally {
8263 tp.kill();
8264 }
8265 } catch (IOException e) {
8266 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008267 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008268 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008269 }
8270 }
8271 }
8272
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008273 static class ItemMatcher {
8274 ArrayList<ComponentName> components;
8275 ArrayList<String> strings;
8276 ArrayList<Integer> objects;
8277 boolean all;
8278
8279 ItemMatcher() {
8280 all = true;
8281 }
8282
8283 void build(String name) {
8284 ComponentName componentName = ComponentName.unflattenFromString(name);
8285 if (componentName != null) {
8286 if (components == null) {
8287 components = new ArrayList<ComponentName>();
8288 }
8289 components.add(componentName);
8290 all = false;
8291 } else {
8292 int objectId = 0;
8293 // Not a '/' separated full component name; maybe an object ID?
8294 try {
8295 objectId = Integer.parseInt(name, 16);
8296 if (objects == null) {
8297 objects = new ArrayList<Integer>();
8298 }
8299 objects.add(objectId);
8300 all = false;
8301 } catch (RuntimeException e) {
8302 // Not an integer; just do string match.
8303 if (strings == null) {
8304 strings = new ArrayList<String>();
8305 }
8306 strings.add(name);
8307 all = false;
8308 }
8309 }
8310 }
8311
8312 int build(String[] args, int opti) {
8313 for (; opti<args.length; opti++) {
8314 String name = args[opti];
8315 if ("--".equals(name)) {
8316 return opti+1;
8317 }
8318 build(name);
8319 }
8320 return opti;
8321 }
8322
8323 boolean match(Object object, ComponentName comp) {
8324 if (all) {
8325 return true;
8326 }
8327 if (components != null) {
8328 for (int i=0; i<components.size(); i++) {
8329 if (components.get(i).equals(comp)) {
8330 return true;
8331 }
8332 }
8333 }
8334 if (objects != null) {
8335 for (int i=0; i<objects.size(); i++) {
8336 if (System.identityHashCode(object) == objects.get(i)) {
8337 return true;
8338 }
8339 }
8340 }
8341 if (strings != null) {
8342 String flat = comp.flattenToString();
8343 for (int i=0; i<strings.size(); i++) {
8344 if (flat.contains(strings.get(i))) {
8345 return true;
8346 }
8347 }
8348 }
8349 return false;
8350 }
8351 }
8352
Dianne Hackborn625ac272010-09-17 18:29:22 -07008353 /**
8354 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008355 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008356 * - the cmd arg isn't the flattened component name of an existing activity:
8357 * dump all activity whose component contains the cmd as a substring
8358 * - A hex number of the ActivityRecord object instance.
8359 */
8360 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8361 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008362 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008363
8364 if ("all".equals(name)) {
8365 synchronized (this) {
8366 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008367 activities.add(r1);
8368 }
8369 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008370 } else if ("top".equals(name)) {
8371 synchronized (this) {
8372 final int N = mMainStack.mHistory.size();
8373 if (N > 0) {
8374 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8375 }
8376 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008377 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008378 ItemMatcher matcher = new ItemMatcher();
8379 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008380
8381 synchronized (this) {
8382 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008383 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008384 activities.add(r1);
8385 }
8386 }
8387 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008388 }
8389
8390 if (activities.size() <= 0) {
8391 return false;
8392 }
8393
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008394 String[] newArgs = new String[args.length - opti];
8395 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8396
Dianne Hackborn30d71892010-12-11 10:37:55 -08008397 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008398 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008399 for (int i=activities.size()-1; i>=0; i--) {
8400 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008401 if (needSep) {
8402 pw.println();
8403 }
8404 needSep = true;
8405 synchronized (this) {
8406 if (lastTask != r.task) {
8407 lastTask = r.task;
8408 pw.print("TASK "); pw.print(lastTask.affinity);
8409 pw.print(" id="); pw.println(lastTask.taskId);
8410 if (dumpAll) {
8411 lastTask.dump(pw, " ");
8412 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008413 }
8414 }
8415 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008416 }
8417 return true;
8418 }
8419
8420 /**
8421 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8422 * there is a thread associated with the activity.
8423 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008424 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008425 final ActivityRecord r, String[] args, boolean dumpAll) {
8426 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008427 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008428 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8429 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8430 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008431 if (r.app != null) pw.println(r.app.pid);
8432 else pw.println("(not running)");
8433 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008434 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008435 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008436 }
8437 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008438 // flush anything that is already in the PrintWriter since the thread is going
8439 // to write to the file descriptor directly
8440 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008441 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008442 TransferPipe tp = new TransferPipe();
8443 try {
8444 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8445 innerPrefix, args);
8446 tp.go(fd);
8447 } finally {
8448 tp.kill();
8449 }
8450 } catch (IOException e) {
8451 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008452 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008453 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008454 }
8455 }
8456 }
8457
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008458 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8459 int opti, boolean dumpAll) {
8460 boolean needSep = false;
8461
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008462 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008463 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008464 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008465 pw.println(" Registered Receivers:");
8466 Iterator it = mRegisteredReceivers.values().iterator();
8467 while (it.hasNext()) {
8468 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008469 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008470 r.dump(pw, " ");
8471 }
8472 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008473
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008474 pw.println();
8475 pw.println(" Receiver Resolver Table:");
8476 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008477 needSep = true;
8478 }
8479
8480 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8481 || mPendingBroadcast != null) {
8482 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008483 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008484 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008485 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008486 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8487 pw.println(" Broadcast #" + i + ":");
8488 mParallelBroadcasts.get(i).dump(pw, " ");
8489 }
8490 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008491 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008492 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008493 }
8494 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8495 pw.println(" Serialized Broadcast #" + i + ":");
8496 mOrderedBroadcasts.get(i).dump(pw, " ");
8497 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008498 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008499 pw.println(" Pending broadcast:");
8500 if (mPendingBroadcast != null) {
8501 mPendingBroadcast.dump(pw, " ");
8502 } else {
8503 pw.println(" (null)");
8504 }
8505 needSep = true;
8506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008507
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008508 if (needSep) {
8509 pw.println();
8510 }
8511 pw.println(" Historical broadcasts:");
8512 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8513 BroadcastRecord r = mBroadcastHistory[i];
8514 if (r == null) {
8515 break;
8516 }
8517 if (dumpAll) {
8518 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8519 r.dump(pw, " ");
8520 } else {
8521 if (i >= 50) {
8522 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008523 break;
8524 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008525 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008526 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008527 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008528 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008529
8530 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008531 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008532 pw.println(" Sticky broadcasts:");
8533 StringBuilder sb = new StringBuilder(128);
8534 for (Map.Entry<String, ArrayList<Intent>> ent
8535 : mStickyBroadcasts.entrySet()) {
8536 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008537 if (dumpAll) {
8538 pw.println(":");
8539 ArrayList<Intent> intents = ent.getValue();
8540 final int N = intents.size();
8541 for (int i=0; i<N; i++) {
8542 sb.setLength(0);
8543 sb.append(" Intent: ");
8544 intents.get(i).toShortString(sb, true, false);
8545 pw.println(sb.toString());
8546 Bundle bundle = intents.get(i).getExtras();
8547 if (bundle != null) {
8548 pw.print(" ");
8549 pw.println(bundle.toString());
8550 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008551 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008552 } else {
8553 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008554 }
8555 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008556 needSep = true;
8557 }
8558
8559 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008560 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008561 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008562 pw.println(" mHandler:");
8563 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008564 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008565 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008566
8567 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008568 }
8569
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008570 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008571 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008572 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008573
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008574 ItemMatcher matcher = new ItemMatcher();
8575 matcher.build(args, opti);
8576
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008577 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8578 if (mServices.size() > 0) {
8579 pw.println(" Active services:");
8580 long nowReal = SystemClock.elapsedRealtime();
8581 Iterator<ServiceRecord> it = mServices.values().iterator();
8582 needSep = false;
8583 while (it.hasNext()) {
8584 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008585 if (!matcher.match(r, r.name)) {
8586 continue;
8587 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008588 if (needSep) {
8589 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008590 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008591 pw.print(" * "); pw.println(r);
8592 if (dumpAll) {
8593 r.dump(pw, " ");
8594 needSep = true;
8595 } else {
8596 pw.print(" app="); pw.println(r.app);
8597 pw.print(" created=");
8598 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8599 pw.print(" started="); pw.print(r.startRequested);
8600 pw.print(" connections="); pw.println(r.connections.size());
8601 }
8602 if (dumpClient && r.app != null && r.app.thread != null) {
8603 pw.println(" Client:");
8604 pw.flush();
8605 try {
8606 TransferPipe tp = new TransferPipe();
8607 try {
8608 r.app.thread.dumpService(
8609 tp.getWriteFd().getFileDescriptor(), r, args);
8610 tp.setBufferPrefix(" ");
8611 // Short timeout, since blocking here can
8612 // deadlock with the application.
8613 tp.go(fd, 2000);
8614 } finally {
8615 tp.kill();
8616 }
8617 } catch (IOException e) {
8618 pw.println(" Failure while dumping the service: " + e);
8619 } catch (RemoteException e) {
8620 pw.println(" Got a RemoteException while dumping the service");
8621 }
8622 needSep = true;
8623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008624 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008625 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008627
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008628 if (mPendingServices.size() > 0) {
8629 if (needSep) pw.println(" ");
8630 pw.println(" Pending services:");
8631 for (int i=0; i<mPendingServices.size(); i++) {
8632 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008633 if (!matcher.match(r, r.name)) {
8634 continue;
8635 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008636 pw.print(" * Pending "); pw.println(r);
8637 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008638 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008639 needSep = true;
8640 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008641
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008642 if (mRestartingServices.size() > 0) {
8643 if (needSep) pw.println(" ");
8644 pw.println(" Restarting services:");
8645 for (int i=0; i<mRestartingServices.size(); i++) {
8646 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008647 if (!matcher.match(r, r.name)) {
8648 continue;
8649 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008650 pw.print(" * Restarting "); pw.println(r);
8651 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008652 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008653 needSep = true;
8654 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008655
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008656 if (mStoppingServices.size() > 0) {
8657 if (needSep) pw.println(" ");
8658 pw.println(" Stopping services:");
8659 for (int i=0; i<mStoppingServices.size(); i++) {
8660 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008661 if (!matcher.match(r, r.name)) {
8662 continue;
8663 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008664 pw.print(" * Stopping "); pw.println(r);
8665 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008666 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008667 needSep = true;
8668 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008669
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008670 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008671 if (mServiceConnections.size() > 0) {
8672 if (needSep) pw.println(" ");
8673 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008674 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008675 = mServiceConnections.values().iterator();
8676 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008677 ArrayList<ConnectionRecord> r = it.next();
8678 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008679 ConnectionRecord cr = r.get(i);
8680 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8681 continue;
8682 }
8683 pw.print(" * "); pw.println(cr);
8684 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008685 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008686 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008687 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008688 }
8689 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008690
8691 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008692 }
8693
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008694 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8695 int opti, boolean dumpAll) {
8696 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008697
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008698 ItemMatcher matcher = new ItemMatcher();
8699 matcher.build(args, opti);
8700
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008701 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8702 if (mProvidersByClass.size() > 0) {
8703 if (needSep) pw.println(" ");
8704 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008705 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008706 = mProvidersByClass.entrySet().iterator();
8707 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008708 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008709 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008710 ComponentName comp = e.getKey();
8711 String cls = comp.getClassName();
8712 int end = cls.lastIndexOf('.');
8713 if (end > 0 && end < (cls.length()-2)) {
8714 cls = cls.substring(end+1);
8715 }
8716 if (!matcher.match(r, comp)) {
8717 continue;
8718 }
8719 pw.print(" * "); pw.print(cls); pw.print(" (");
8720 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008721 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008722 pw.println();
8723 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008724 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008725 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008726 if (r.proc != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008727 pw.println(":");
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07008728 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008729 } else {
8730 pw.println();
8731 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008732 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008733 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008734 needSep = true;
8735 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008736
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008737 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008738 if (mProvidersByName.size() > 0) {
8739 pw.println(" ");
8740 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008741 Iterator<Map.Entry<String, ContentProviderRecord>> it
8742 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008743 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008744 Map.Entry<String, ContentProviderRecord> e = it.next();
8745 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008746 if (!matcher.match(r, r.name)) {
8747 continue;
8748 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008749 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8750 pw.println(r);
8751 }
8752 needSep = true;
8753 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008754 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008755
8756 if (mLaunchingProviders.size() > 0) {
8757 if (needSep) pw.println(" ");
8758 pw.println(" Launching content providers:");
8759 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8760 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8761 pw.println(mLaunchingProviders.get(i));
8762 }
8763 needSep = true;
8764 }
8765
8766 if (mGrantedUriPermissions.size() > 0) {
8767 pw.println();
8768 pw.println("Granted Uri Permissions:");
8769 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8770 int uid = mGrantedUriPermissions.keyAt(i);
8771 HashMap<Uri, UriPermission> perms
8772 = mGrantedUriPermissions.valueAt(i);
8773 pw.print(" * UID "); pw.print(uid);
8774 pw.println(" holds:");
8775 for (UriPermission perm : perms.values()) {
8776 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008777 if (dumpAll) {
8778 perm.dump(pw, " ");
8779 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008780 }
8781 }
8782 needSep = true;
8783 }
8784
8785 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008786 }
8787
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008788 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8789 int opti, boolean dumpAll) {
8790 boolean needSep = false;
8791
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008792 if (this.mIntentSenderRecords.size() > 0) {
8793 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8794 Iterator<WeakReference<PendingIntentRecord>> it
8795 = mIntentSenderRecords.values().iterator();
8796 while (it.hasNext()) {
8797 WeakReference<PendingIntentRecord> ref = it.next();
8798 PendingIntentRecord rec = ref != null ? ref.get(): null;
8799 needSep = true;
8800 if (rec != null) {
8801 pw.print(" * "); pw.println(rec);
8802 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008803 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008804 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008805 } else {
8806 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008807 }
8808 }
8809 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008810
8811 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008812 }
8813
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008814 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8815 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008816 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008817 boolean needNL = false;
8818 final String innerPrefix = prefix + " ";
8819 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008820 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008821 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008822 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008823 if (needNL) {
8824 pw.println(" ");
8825 needNL = false;
8826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008827 if (lastTask != r.task) {
8828 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008829 pw.print(prefix);
8830 pw.print(full ? "* " : " ");
8831 pw.println(lastTask);
8832 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008833 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008834 } else if (complete) {
8835 // Complete + brief == give a summary. Isn't that obvious?!?
8836 if (lastTask.intent != null) {
8837 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8838 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008839 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008840 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008841 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8842 pw.print(" #"); pw.print(i); pw.print(": ");
8843 pw.println(r);
8844 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008845 r.dump(pw, innerPrefix);
8846 } else if (complete) {
8847 // Complete + brief == give a summary. Isn't that obvious?!?
8848 pw.print(innerPrefix); pw.println(r.intent);
8849 if (r.app != null) {
8850 pw.print(innerPrefix); pw.println(r.app);
8851 }
8852 }
8853 if (client && r.app != null && r.app.thread != null) {
8854 // flush anything that is already in the PrintWriter since the thread is going
8855 // to write to the file descriptor directly
8856 pw.flush();
8857 try {
8858 TransferPipe tp = new TransferPipe();
8859 try {
8860 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8861 innerPrefix, args);
8862 // Short timeout, since blocking here can
8863 // deadlock with the application.
8864 tp.go(fd, 2000);
8865 } finally {
8866 tp.kill();
8867 }
8868 } catch (IOException e) {
8869 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8870 } catch (RemoteException e) {
8871 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8872 }
8873 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008874 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008875 }
8876 }
8877
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008878 private static String buildOomTag(String prefix, String space, int val, int base) {
8879 if (val == base) {
8880 if (space == null) return prefix;
8881 return prefix + " ";
8882 }
8883 return prefix + "+" + Integer.toString(val-base);
8884 }
8885
8886 private static final int dumpProcessList(PrintWriter pw,
8887 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008888 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008889 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008890 final int N = list.size()-1;
8891 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008892 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008893 pw.println(String.format("%s%s #%2d: %s",
8894 prefix, (r.persistent ? persistentLabel : normalLabel),
8895 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008896 if (r.persistent) {
8897 numPers++;
8898 }
8899 }
8900 return numPers;
8901 }
8902
Dianne Hackborn287952c2010-09-22 22:34:31 -07008903 private static final void dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07008904 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008905 String prefix, String normalLabel, String persistentLabel,
8906 boolean inclDetails) {
8907
Dianne Hackborn905577f2011-09-07 18:31:28 -07008908 ArrayList<Pair<ProcessRecord, Integer>> list
8909 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
8910 for (int i=0; i<origList.size(); i++) {
8911 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
8912 }
8913
8914 Comparator<Pair<ProcessRecord, Integer>> comparator
8915 = new Comparator<Pair<ProcessRecord, Integer>>() {
8916 @Override
8917 public int compare(Pair<ProcessRecord, Integer> object1,
8918 Pair<ProcessRecord, Integer> object2) {
8919 if (object1.first.setAdj != object2.first.setAdj) {
8920 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
8921 }
8922 if (object1.second.intValue() != object2.second.intValue()) {
8923 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
8924 }
8925 return 0;
8926 }
8927 };
8928
8929 Collections.sort(list, comparator);
8930
Dianne Hackborn287952c2010-09-22 22:34:31 -07008931 final long curRealtime = SystemClock.elapsedRealtime();
8932 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8933 final long curUptime = SystemClock.uptimeMillis();
8934 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8935
8936 final int N = list.size()-1;
8937 for (int i=N; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008938 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008939 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008940 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8941 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8942 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8943 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
8944 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
8945 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
8946 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
8947 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
8948 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
8949 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
8950 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8951 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
8952 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8953 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
8954 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
8955 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
8956 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
8957 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
8958 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
8959 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
8960 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
8961 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008962 } else {
8963 oomAdj = Integer.toString(r.setAdj);
8964 }
8965 String schedGroup;
8966 switch (r.setSchedGroup) {
8967 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8968 schedGroup = "B";
8969 break;
8970 case Process.THREAD_GROUP_DEFAULT:
8971 schedGroup = "F";
8972 break;
8973 default:
8974 schedGroup = Integer.toString(r.setSchedGroup);
8975 break;
8976 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008977 String foreground;
8978 if (r.foregroundActivities) {
8979 foreground = "A";
8980 } else if (r.foregroundServices) {
8981 foreground = "S";
8982 } else {
8983 foreground = " ";
8984 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008985 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008986 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackborn905577f2011-09-07 18:31:28 -07008987 N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008988 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008989 if (r.adjSource != null || r.adjTarget != null) {
8990 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008991 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008992 if (r.adjTarget instanceof ComponentName) {
8993 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8994 } else if (r.adjTarget != null) {
8995 pw.print(r.adjTarget.toString());
8996 } else {
8997 pw.print("{null}");
8998 }
8999 pw.print("<=");
9000 if (r.adjSource instanceof ProcessRecord) {
9001 pw.print("Proc{");
9002 pw.print(((ProcessRecord)r.adjSource).toShortString());
9003 pw.println("}");
9004 } else if (r.adjSource != null) {
9005 pw.println(r.adjSource.toString());
9006 } else {
9007 pw.println("{null}");
9008 }
9009 }
9010 if (inclDetails) {
9011 pw.print(prefix);
9012 pw.print(" ");
9013 pw.print("oom: max="); pw.print(r.maxAdj);
9014 pw.print(" hidden="); pw.print(r.hiddenAdj);
9015 pw.print(" curRaw="); pw.print(r.curRawAdj);
9016 pw.print(" setRaw="); pw.print(r.setRawAdj);
9017 pw.print(" cur="); pw.print(r.curAdj);
9018 pw.print(" set="); pw.println(r.setAdj);
9019 pw.print(prefix);
9020 pw.print(" ");
9021 pw.print("keeping="); pw.print(r.keeping);
9022 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009023 pw.print(" empty="); pw.print(r.empty);
9024 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009025
9026 if (!r.keeping) {
9027 if (r.lastWakeTime != 0) {
9028 long wtime;
9029 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9030 synchronized (stats) {
9031 wtime = stats.getProcessWakeTime(r.info.uid,
9032 r.pid, curRealtime);
9033 }
9034 long timeUsed = wtime - r.lastWakeTime;
9035 pw.print(prefix);
9036 pw.print(" ");
9037 pw.print("keep awake over ");
9038 TimeUtils.formatDuration(realtimeSince, pw);
9039 pw.print(" used ");
9040 TimeUtils.formatDuration(timeUsed, pw);
9041 pw.print(" (");
9042 pw.print((timeUsed*100)/realtimeSince);
9043 pw.println("%)");
9044 }
9045 if (r.lastCpuTime != 0) {
9046 long timeUsed = r.curCpuTime - r.lastCpuTime;
9047 pw.print(prefix);
9048 pw.print(" ");
9049 pw.print("run cpu over ");
9050 TimeUtils.formatDuration(uptimeSince, pw);
9051 pw.print(" used ");
9052 TimeUtils.formatDuration(timeUsed, pw);
9053 pw.print(" (");
9054 pw.print((timeUsed*100)/uptimeSince);
9055 pw.println("%)");
9056 }
9057 }
9058 }
9059 }
9060 }
9061
Dianne Hackbornb437e092011-08-05 17:50:29 -07009062 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009063 ArrayList<ProcessRecord> procs;
9064 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009065 if (args != null && args.length > start
9066 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009067 procs = new ArrayList<ProcessRecord>();
9068 int pid = -1;
9069 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009070 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009071 } catch (NumberFormatException e) {
9072
9073 }
9074 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9075 ProcessRecord proc = mLruProcesses.get(i);
9076 if (proc.pid == pid) {
9077 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009078 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009079 procs.add(proc);
9080 }
9081 }
9082 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009083 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009084 return null;
9085 }
9086 } else {
9087 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9088 }
9089 }
9090 return procs;
9091 }
9092
9093 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9094 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009095 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009096 if (procs == null) {
9097 return;
9098 }
9099
9100 long uptime = SystemClock.uptimeMillis();
9101 long realtime = SystemClock.elapsedRealtime();
9102 pw.println("Applications Graphics Acceleration Info:");
9103 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9104
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009105 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9106 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009107 if (r.thread != null) {
9108 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9109 pw.flush();
9110 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009111 TransferPipe tp = new TransferPipe();
9112 try {
9113 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9114 tp.go(fd);
9115 } finally {
9116 tp.kill();
9117 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009118 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009119 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009120 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009121 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009122 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009123 pw.flush();
9124 }
9125 }
9126 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009127 }
9128
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009129 final static class MemItem {
9130 final String label;
9131 final long pss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009132 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009133
9134 public MemItem(String _label, long _pss) {
9135 label = _label;
9136 pss = _pss;
9137 }
9138 }
9139
Dianne Hackbornb437e092011-08-05 17:50:29 -07009140 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9141 boolean sort) {
9142 if (sort) {
9143 Collections.sort(items, new Comparator<MemItem>() {
9144 @Override
9145 public int compare(MemItem lhs, MemItem rhs) {
9146 if (lhs.pss < rhs.pss) {
9147 return 1;
9148 } else if (lhs.pss > rhs.pss) {
9149 return -1;
9150 }
9151 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009152 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009153 });
9154 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009155
9156 for (int i=0; i<items.size(); i++) {
9157 MemItem mi = items.get(i);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009158 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
9159 if (mi.subitems != null) {
9160 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9161 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009162 }
9163 }
9164
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009165 final void dumpApplicationMemoryUsage(FileDescriptor fd,
9166 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009167 boolean dumpAll = false;
9168
9169 int opti = 0;
9170 while (opti < args.length) {
9171 String opt = args[opti];
9172 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9173 break;
9174 }
9175 opti++;
9176 if ("-a".equals(opt)) {
9177 dumpAll = true;
9178 } else if ("-h".equals(opt)) {
9179 pw.println("meminfo dump options: [-a] [process]");
9180 pw.println(" -a: include all available information for each process.");
9181 pw.println("If [process] is specified it can be the name or ");
9182 pw.println("pid of a specific process to dump.");
9183 return;
9184 } else {
9185 pw.println("Unknown argument: " + opt + "; use -h for help");
9186 }
9187 }
9188
9189 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009190 if (procs == null) {
9191 return;
9192 }
9193
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009194 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009195 long uptime = SystemClock.uptimeMillis();
9196 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009197
9198 if (procs.size() == 1 || isCheckinRequest) {
9199 dumpAll = true;
9200 }
9201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009202 if (isCheckinRequest) {
9203 // short checkin version
9204 pw.println(uptime + "," + realtime);
9205 pw.flush();
9206 } else {
9207 pw.println("Applications Memory Usage (kB):");
9208 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9209 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009210
Dianne Hackbornb437e092011-08-05 17:50:29 -07009211 String[] innerArgs = new String[args.length-opti];
9212 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9213
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009214 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9215 long nativePss=0, dalvikPss=0, otherPss=0;
9216 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9217
Dianne Hackbornb437e092011-08-05 17:50:29 -07009218 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009219 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9220 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9221 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009222 };
9223 final String[] oomLabel = new String[] {
9224 "System", "Persistent", "Foreground",
9225 "Visible", "Perceptible", "Heavy Weight",
9226 "Backup", "Services", "Home", "Background"
9227 };
9228 long oomPss[] = new long[oomLabel.length];
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009229 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009230
9231 long totalPss = 0;
9232
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009233 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9234 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009235 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009236 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009237 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9238 pw.flush();
9239 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009240 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009241 if (dumpAll) {
9242 try {
9243 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9244 } catch (RemoteException e) {
9245 if (!isCheckinRequest) {
9246 pw.println("Got RemoteException!");
9247 pw.flush();
9248 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009249 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009250 } else {
9251 mi = new Debug.MemoryInfo();
9252 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009253 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009254
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009255 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009256 long myTotalPss = mi.getTotalPss();
9257 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009258 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9259 myTotalPss);
9260 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009261
9262 nativePss += mi.nativePss;
9263 dalvikPss += mi.dalvikPss;
9264 otherPss += mi.otherPss;
9265 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9266 long mem = mi.getOtherPss(j);
9267 miscPss[j] += mem;
9268 otherPss -= mem;
9269 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009270
9271 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9272 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9273 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009274 if (oomProcs[oomIndex] == null) {
9275 oomProcs[oomIndex] = new ArrayList<MemItem>();
9276 }
9277 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009278 break;
9279 }
9280 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009282 }
9283 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009284
9285 if (!isCheckinRequest && procs.size() > 1) {
9286 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9287
9288 catMems.add(new MemItem("Native", nativePss));
9289 catMems.add(new MemItem("Dalvik", dalvikPss));
9290 catMems.add(new MemItem("Unknown", otherPss));
9291 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9292 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9293 }
9294
Dianne Hackbornb437e092011-08-05 17:50:29 -07009295 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9296 for (int j=0; j<oomPss.length; j++) {
9297 if (oomPss[j] != 0) {
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009298 MemItem item = new MemItem(oomLabel[j], oomPss[j]);
9299 item.subitems = oomProcs[j];
9300 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009301 }
9302 }
9303
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009304 pw.println();
9305 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009306 dumpMemItems(pw, " ", procMems, true);
9307 pw.println();
9308 pw.println("Total PSS by OOM adjustment:");
9309 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009310 pw.println();
9311 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009312 dumpMemItems(pw, " ", catMems, true);
9313 pw.println();
9314 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009316 }
9317
9318 /**
9319 * Searches array of arguments for the specified string
9320 * @param args array of argument strings
9321 * @param value value to search for
9322 * @return true if the value is contained in the array
9323 */
9324 private static boolean scanArgs(String[] args, String value) {
9325 if (args != null) {
9326 for (String arg : args) {
9327 if (value.equals(arg)) {
9328 return true;
9329 }
9330 }
9331 }
9332 return false;
9333 }
9334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009335 private final void killServicesLocked(ProcessRecord app,
9336 boolean allowRestart) {
9337 // Report disconnected services.
9338 if (false) {
9339 // XXX we are letting the client link to the service for
9340 // death notifications.
9341 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009342 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009343 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009344 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009345 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009346 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009347 = r.connections.values().iterator();
9348 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009349 ArrayList<ConnectionRecord> cl = jt.next();
9350 for (int i=0; i<cl.size(); i++) {
9351 ConnectionRecord c = cl.get(i);
9352 if (c.binding.client != app) {
9353 try {
9354 //c.conn.connected(r.className, null);
9355 } catch (Exception e) {
9356 // todo: this should be asynchronous!
9357 Slog.w(TAG, "Exception thrown disconnected servce "
9358 + r.shortName
9359 + " from app " + app.processName, e);
9360 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009361 }
9362 }
9363 }
9364 }
9365 }
9366 }
9367 }
9368
9369 // Clean up any connections this application has to other services.
9370 if (app.connections.size() > 0) {
9371 Iterator<ConnectionRecord> it = app.connections.iterator();
9372 while (it.hasNext()) {
9373 ConnectionRecord r = it.next();
9374 removeConnectionLocked(r, app, null);
9375 }
9376 }
9377 app.connections.clear();
9378
9379 if (app.services.size() != 0) {
9380 // Any services running in the application need to be placed
9381 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009382 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009383 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009384 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009385 synchronized (sr.stats.getBatteryStats()) {
9386 sr.stats.stopLaunchedLocked();
9387 }
9388 sr.app = null;
9389 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009390 if (mStoppingServices.remove(sr)) {
9391 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9392 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009393
9394 boolean hasClients = sr.bindings.size() > 0;
9395 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009396 Iterator<IntentBindRecord> bindings
9397 = sr.bindings.values().iterator();
9398 while (bindings.hasNext()) {
9399 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009400 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009401 + ": shouldUnbind=" + b.hasBound);
9402 b.binder = null;
9403 b.requested = b.received = b.hasBound = false;
9404 }
9405 }
9406
Dianne Hackborn070783f2010-12-29 16:46:28 -08009407 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9408 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009409 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009410 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009411 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009412 sr.crashCount, sr.shortName, app.pid);
9413 bringDownServiceLocked(sr, true);
9414 } else if (!allowRestart) {
9415 bringDownServiceLocked(sr, true);
9416 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009417 boolean canceled = scheduleServiceRestartLocked(sr, true);
9418
9419 // Should the service remain running? Note that in the
9420 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009421 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009422 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9423 if (sr.pendingStarts.size() == 0) {
9424 sr.startRequested = false;
9425 if (!hasClients) {
9426 // Whoops, no reason to restart!
9427 bringDownServiceLocked(sr, true);
9428 }
9429 }
9430 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009431 }
9432 }
9433
9434 if (!allowRestart) {
9435 app.services.clear();
9436 }
9437 }
9438
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009439 // Make sure we have no more records on the stopping list.
9440 int i = mStoppingServices.size();
9441 while (i > 0) {
9442 i--;
9443 ServiceRecord sr = mStoppingServices.get(i);
9444 if (sr.app == app) {
9445 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009446 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009447 }
9448 }
9449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009450 app.executingServices.clear();
9451 }
9452
9453 private final void removeDyingProviderLocked(ProcessRecord proc,
9454 ContentProviderRecord cpr) {
9455 synchronized (cpr) {
9456 cpr.launchingApp = null;
9457 cpr.notifyAll();
9458 }
9459
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009460 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009461 String names[] = cpr.info.authority.split(";");
9462 for (int j = 0; j < names.length; j++) {
9463 mProvidersByName.remove(names[j]);
9464 }
9465
9466 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9467 while (cit.hasNext()) {
9468 ProcessRecord capp = cit.next();
9469 if (!capp.persistent && capp.thread != null
9470 && capp.pid != 0
9471 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009472 Slog.i(TAG, "Kill " + capp.processName
9473 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009474 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -07009475 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009476 capp.processName, capp.setAdj, "dying provider "
9477 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009478 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009479 }
9480 }
9481
9482 mLaunchingProviders.remove(cpr);
9483 }
9484
9485 /**
9486 * Main code for cleaning up a process when it has gone away. This is
9487 * called both as a result of the process dying, or directly when stopping
9488 * a process when running in single process mode.
9489 */
9490 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009491 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009492 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009493 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494 }
9495
Dianne Hackborn36124872009-10-08 16:22:03 -07009496 mProcessesToGc.remove(app);
9497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009498 // Dismiss any open dialogs.
9499 if (app.crashDialog != null) {
9500 app.crashDialog.dismiss();
9501 app.crashDialog = null;
9502 }
9503 if (app.anrDialog != null) {
9504 app.anrDialog.dismiss();
9505 app.anrDialog = null;
9506 }
9507 if (app.waitDialog != null) {
9508 app.waitDialog.dismiss();
9509 app.waitDialog = null;
9510 }
9511
9512 app.crashing = false;
9513 app.notResponding = false;
9514
9515 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009516 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009517 app.thread = null;
9518 app.forcingToForeground = null;
9519 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009520 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009521 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009522 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009523
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009524 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009525
9526 boolean restart = false;
9527
9528 int NL = mLaunchingProviders.size();
9529
9530 // Remove published content providers.
9531 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009532 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009533 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009534 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009535 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009536 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009537
9538 // See if someone is waiting for this provider... in which
9539 // case we don't remove it, but just let it restart.
9540 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009541 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009542 for (; i<NL; i++) {
9543 if (mLaunchingProviders.get(i) == cpr) {
9544 restart = true;
9545 break;
9546 }
9547 }
9548 } else {
9549 i = NL;
9550 }
9551
9552 if (i >= NL) {
9553 removeDyingProviderLocked(app, cpr);
9554 NL = mLaunchingProviders.size();
9555 }
9556 }
9557 app.pubProviders.clear();
9558 }
9559
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009560 // Take care of any launching providers waiting for this process.
9561 if (checkAppInLaunchingProvidersLocked(app, false)) {
9562 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009565 // Unregister from connected content providers.
9566 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009567 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009568 while (it.hasNext()) {
9569 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9570 cpr.clients.remove(app);
9571 }
9572 app.conProviders.clear();
9573 }
9574
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009575 // At this point there may be remaining entries in mLaunchingProviders
9576 // where we were the only one waiting, so they are no longer of use.
9577 // Look for these and clean up if found.
9578 // XXX Commented out for now. Trying to figure out a way to reproduce
9579 // the actual situation to identify what is actually going on.
9580 if (false) {
9581 for (int i=0; i<NL; i++) {
9582 ContentProviderRecord cpr = (ContentProviderRecord)
9583 mLaunchingProviders.get(i);
9584 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9585 synchronized (cpr) {
9586 cpr.launchingApp = null;
9587 cpr.notifyAll();
9588 }
9589 }
9590 }
9591 }
9592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009593 skipCurrentReceiverLocked(app);
9594
9595 // Unregister any receivers.
9596 if (app.receivers.size() > 0) {
9597 Iterator<ReceiverList> it = app.receivers.iterator();
9598 while (it.hasNext()) {
9599 removeReceiverLocked(it.next());
9600 }
9601 app.receivers.clear();
9602 }
9603
Christopher Tate181fafa2009-05-14 11:12:14 -07009604 // If the app is undergoing backup, tell the backup manager about it
9605 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009606 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009607 try {
9608 IBackupManager bm = IBackupManager.Stub.asInterface(
9609 ServiceManager.getService(Context.BACKUP_SERVICE));
9610 bm.agentDisconnected(app.info.packageName);
9611 } catch (RemoteException e) {
9612 // can't happen; backup manager is local
9613 }
9614 }
9615
Jeff Sharkey287bd832011-05-28 19:36:26 -07009616 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009618 // If the caller is restarting this app, then leave it in its
9619 // current lists and let the caller take care of it.
9620 if (restarting) {
9621 return;
9622 }
9623
9624 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009625 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009626 "Removing non-persistent process during cleanup: " + app);
9627 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009628 if (mHeavyWeightProcess == app) {
9629 mHeavyWeightProcess = null;
9630 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9631 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009632 } else if (!app.removed) {
9633 // This app is persistent, so we need to keep its record around.
9634 // If it is not already on the pending app list, add it there
9635 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009636 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9637 mPersistentStartingProcesses.add(app);
9638 restart = true;
9639 }
9640 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009641 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9642 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009643 mProcessesOnHold.remove(app);
9644
The Android Open Source Project4df24232009-03-05 14:34:35 -08009645 if (app == mHomeProcess) {
9646 mHomeProcess = null;
9647 }
9648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009649 if (restart) {
9650 // We have components that still need to be running in the
9651 // process, so re-launch it.
9652 mProcessNames.put(app.processName, app.info.uid, app);
9653 startProcessLocked(app, "restart", app.processName);
9654 } else if (app.pid > 0 && app.pid != MY_PID) {
9655 // Goodbye!
9656 synchronized (mPidsSelfLocked) {
9657 mPidsSelfLocked.remove(app.pid);
9658 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9659 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009660 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009661 }
9662 }
9663
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009664 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9665 // Look through the content providers we are waiting to have launched,
9666 // and if any run in this process then either schedule a restart of
9667 // the process or kill the client waiting for it if this process has
9668 // gone bad.
9669 int NL = mLaunchingProviders.size();
9670 boolean restart = false;
9671 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009672 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009673 if (cpr.launchingApp == app) {
9674 if (!alwaysBad && !app.bad) {
9675 restart = true;
9676 } else {
9677 removeDyingProviderLocked(app, cpr);
9678 NL = mLaunchingProviders.size();
9679 }
9680 }
9681 }
9682 return restart;
9683 }
9684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685 // =========================================================
9686 // SERVICES
9687 // =========================================================
9688
9689 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9690 ActivityManager.RunningServiceInfo info =
9691 new ActivityManager.RunningServiceInfo();
9692 info.service = r.name;
9693 if (r.app != null) {
9694 info.pid = r.app.pid;
9695 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009696 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009697 info.process = r.processName;
9698 info.foreground = r.isForeground;
9699 info.activeSince = r.createTime;
9700 info.started = r.startRequested;
9701 info.clientCount = r.connections.size();
9702 info.crashCount = r.crashCount;
9703 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009704 if (r.isForeground) {
9705 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9706 }
9707 if (r.startRequested) {
9708 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9709 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009710 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009711 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9712 }
9713 if (r.app != null && r.app.persistent) {
9714 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9715 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009716
9717 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9718 for (int i=0; i<connl.size(); i++) {
9719 ConnectionRecord conn = connl.get(i);
9720 if (conn.clientLabel != 0) {
9721 info.clientPackage = conn.binding.client.info.packageName;
9722 info.clientLabel = conn.clientLabel;
9723 return info;
9724 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009725 }
9726 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009727 return info;
9728 }
9729
9730 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9731 int flags) {
9732 synchronized (this) {
9733 ArrayList<ActivityManager.RunningServiceInfo> res
9734 = new ArrayList<ActivityManager.RunningServiceInfo>();
9735
9736 if (mServices.size() > 0) {
9737 Iterator<ServiceRecord> it = mServices.values().iterator();
9738 while (it.hasNext() && res.size() < maxNum) {
9739 res.add(makeRunningServiceInfoLocked(it.next()));
9740 }
9741 }
9742
9743 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9744 ServiceRecord r = mRestartingServices.get(i);
9745 ActivityManager.RunningServiceInfo info =
9746 makeRunningServiceInfoLocked(r);
9747 info.restarting = r.nextRestartTime;
9748 res.add(info);
9749 }
9750
9751 return res;
9752 }
9753 }
9754
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009755 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9756 synchronized (this) {
9757 ServiceRecord r = mServices.get(name);
9758 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009759 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9760 for (int i=0; i<conn.size(); i++) {
9761 if (conn.get(i).clientIntent != null) {
9762 return conn.get(i).clientIntent;
9763 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009764 }
9765 }
9766 }
9767 }
9768 return null;
9769 }
9770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009771 private final ServiceRecord findServiceLocked(ComponentName name,
9772 IBinder token) {
9773 ServiceRecord r = mServices.get(name);
9774 return r == token ? r : null;
9775 }
9776
9777 private final class ServiceLookupResult {
9778 final ServiceRecord record;
9779 final String permission;
9780
9781 ServiceLookupResult(ServiceRecord _record, String _permission) {
9782 record = _record;
9783 permission = _permission;
9784 }
9785 };
9786
9787 private ServiceLookupResult findServiceLocked(Intent service,
9788 String resolvedType) {
9789 ServiceRecord r = null;
9790 if (service.getComponent() != null) {
9791 r = mServices.get(service.getComponent());
9792 }
9793 if (r == null) {
9794 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9795 r = mServicesByIntent.get(filter);
9796 }
9797
9798 if (r == null) {
9799 try {
9800 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009801 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009802 service, resolvedType, 0);
9803 ServiceInfo sInfo =
9804 rInfo != null ? rInfo.serviceInfo : null;
9805 if (sInfo == null) {
9806 return null;
9807 }
9808
9809 ComponentName name = new ComponentName(
9810 sInfo.applicationInfo.packageName, sInfo.name);
9811 r = mServices.get(name);
9812 } catch (RemoteException ex) {
9813 // pm is in same process, this will never happen.
9814 }
9815 }
9816 if (r != null) {
9817 int callingPid = Binder.getCallingPid();
9818 int callingUid = Binder.getCallingUid();
9819 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009820 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009821 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009822 if (!r.exported) {
9823 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9824 + " from pid=" + callingPid
9825 + ", uid=" + callingUid
9826 + " that is not exported from uid " + r.appInfo.uid);
9827 return new ServiceLookupResult(null, "not exported from uid "
9828 + r.appInfo.uid);
9829 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009830 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009831 + " from pid=" + callingPid
9832 + ", uid=" + callingUid
9833 + " requires " + r.permission);
9834 return new ServiceLookupResult(null, r.permission);
9835 }
9836 return new ServiceLookupResult(r, null);
9837 }
9838 return null;
9839 }
9840
9841 private class ServiceRestarter implements Runnable {
9842 private ServiceRecord mService;
9843
9844 void setService(ServiceRecord service) {
9845 mService = service;
9846 }
9847
9848 public void run() {
9849 synchronized(ActivityManagerService.this) {
9850 performServiceRestartLocked(mService);
9851 }
9852 }
9853 }
9854
9855 private ServiceLookupResult retrieveServiceLocked(Intent service,
9856 String resolvedType, int callingPid, int callingUid) {
9857 ServiceRecord r = null;
9858 if (service.getComponent() != null) {
9859 r = mServices.get(service.getComponent());
9860 }
9861 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9862 r = mServicesByIntent.get(filter);
9863 if (r == null) {
9864 try {
9865 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009866 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009867 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009868 ServiceInfo sInfo =
9869 rInfo != null ? rInfo.serviceInfo : null;
9870 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009871 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009872 ": not found");
9873 return null;
9874 }
9875
9876 ComponentName name = new ComponentName(
9877 sInfo.applicationInfo.packageName, sInfo.name);
9878 r = mServices.get(name);
9879 if (r == null) {
9880 filter = new Intent.FilterComparison(service.cloneFilter());
9881 ServiceRestarter res = new ServiceRestarter();
9882 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9883 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9884 synchronized (stats) {
9885 ss = stats.getServiceStatsLocked(
9886 sInfo.applicationInfo.uid, sInfo.packageName,
9887 sInfo.name);
9888 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009889 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009890 res.setService(r);
9891 mServices.put(name, r);
9892 mServicesByIntent.put(filter, r);
9893
9894 // Make sure this component isn't in the pending list.
9895 int N = mPendingServices.size();
9896 for (int i=0; i<N; i++) {
9897 ServiceRecord pr = mPendingServices.get(i);
9898 if (pr.name.equals(name)) {
9899 mPendingServices.remove(i);
9900 i--;
9901 N--;
9902 }
9903 }
9904 }
9905 } catch (RemoteException ex) {
9906 // pm is in same process, this will never happen.
9907 }
9908 }
9909 if (r != null) {
9910 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009911 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009912 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009913 if (!r.exported) {
9914 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9915 + " from pid=" + callingPid
9916 + ", uid=" + callingUid
9917 + " that is not exported from uid " + r.appInfo.uid);
9918 return new ServiceLookupResult(null, "not exported from uid "
9919 + r.appInfo.uid);
9920 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009921 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009922 + " from pid=" + callingPid
9923 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009924 + " requires " + r.permission);
9925 return new ServiceLookupResult(null, r.permission);
9926 }
9927 return new ServiceLookupResult(r, null);
9928 }
9929 return null;
9930 }
9931
Dianne Hackborn287952c2010-09-22 22:34:31 -07009932 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9933 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9934 + why + " of " + r + " in app " + r.app);
9935 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9936 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009937 long now = SystemClock.uptimeMillis();
9938 if (r.executeNesting == 0 && r.app != null) {
9939 if (r.app.executingServices.size() == 0) {
9940 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9941 msg.obj = r.app;
9942 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9943 }
9944 r.app.executingServices.add(r);
9945 }
9946 r.executeNesting++;
9947 r.executingStart = now;
9948 }
9949
9950 private final void sendServiceArgsLocked(ServiceRecord r,
9951 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009952 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009953 if (N == 0) {
9954 return;
9955 }
9956
Dianne Hackborn39792d22010-08-19 18:01:52 -07009957 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009958 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009959 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009960 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9961 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009962 if (si.intent == null && N > 1) {
9963 // If somehow we got a dummy null intent in the middle,
9964 // then skip it. DO NOT skip a null intent when it is
9965 // the only one in the list -- this is to support the
9966 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009967 continue;
9968 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009969 si.deliveredTime = SystemClock.uptimeMillis();
9970 r.deliveredStarts.add(si);
9971 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009972 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009973 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009974 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009975 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009976 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009977 if (!oomAdjusted) {
9978 oomAdjusted = true;
9979 updateOomAdjLocked(r.app);
9980 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009981 int flags = 0;
9982 if (si.deliveryCount > 0) {
9983 flags |= Service.START_FLAG_RETRY;
9984 }
9985 if (si.doneExecutingCount > 0) {
9986 flags |= Service.START_FLAG_REDELIVERY;
9987 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009988 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009989 } catch (RemoteException e) {
9990 // Remote process gone... we'll let the normal cleanup take
9991 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009992 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009993 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009994 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009995 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009996 break;
9997 }
9998 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009999 }
10000
10001 private final boolean requestServiceBindingLocked(ServiceRecord r,
10002 IntentBindRecord i, boolean rebind) {
10003 if (r.app == null || r.app.thread == null) {
10004 // If service is not currently running, can't yet bind.
10005 return false;
10006 }
10007 if ((!i.requested || rebind) && i.apps.size() > 0) {
10008 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010009 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010010 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10011 if (!rebind) {
10012 i.requested = true;
10013 }
10014 i.hasBound = true;
10015 i.doRebind = false;
10016 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010017 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010018 return false;
10019 }
10020 }
10021 return true;
10022 }
10023
10024 private final void requestServiceBindingsLocked(ServiceRecord r) {
10025 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10026 while (bindings.hasNext()) {
10027 IntentBindRecord i = bindings.next();
10028 if (!requestServiceBindingLocked(r, i, false)) {
10029 break;
10030 }
10031 }
10032 }
10033
10034 private final void realStartServiceLocked(ServiceRecord r,
10035 ProcessRecord app) throws RemoteException {
10036 if (app.thread == null) {
10037 throw new RemoteException();
10038 }
10039
10040 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010041 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010042
10043 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010044 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010045 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010046
10047 boolean created = false;
10048 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010049 mStringBuilder.setLength(0);
10050 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010051 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010052 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010053 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010054 synchronized (r.stats.getBatteryStats()) {
10055 r.stats.startLaunchedLocked();
10056 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010057 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010058 app.thread.scheduleCreateService(r, r.serviceInfo,
10059 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010060 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010061 created = true;
10062 } finally {
10063 if (!created) {
10064 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010065 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010066 }
10067 }
10068
10069 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010070
10071 // If the service is in the started state, and there are no
10072 // pending arguments, then fake up one so its onStartCommand() will
10073 // be called.
10074 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010075 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10076 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010077 }
10078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010079 sendServiceArgsLocked(r, true);
10080 }
10081
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010082 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10083 boolean allowCancel) {
10084 boolean canceled = false;
10085
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010086 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010087 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010088 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010089
Dianne Hackborn070783f2010-12-29 16:46:28 -080010090 if ((r.serviceInfo.applicationInfo.flags
10091 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10092 minDuration /= 4;
10093 }
10094
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010095 // Any delivered but not yet finished starts should be put back
10096 // on the pending list.
10097 final int N = r.deliveredStarts.size();
10098 if (N > 0) {
10099 for (int i=N-1; i>=0; i--) {
10100 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010101 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010102 if (si.intent == null) {
10103 // We'll generate this again if needed.
10104 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10105 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10106 r.pendingStarts.add(0, si);
10107 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10108 dur *= 2;
10109 if (minDuration < dur) minDuration = dur;
10110 if (resetTime < dur) resetTime = dur;
10111 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010112 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010113 + r.name);
10114 canceled = true;
10115 }
10116 }
10117 r.deliveredStarts.clear();
10118 }
10119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010120 r.totalRestartCount++;
10121 if (r.restartDelay == 0) {
10122 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010123 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010124 } else {
10125 // If it has been a "reasonably long time" since the service
10126 // was started, then reset our restart duration back to
10127 // the beginning, so we don't infinitely increase the duration
10128 // on a service that just occasionally gets killed (which is
10129 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010130 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010131 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010132 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010133 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010134 if ((r.serviceInfo.applicationInfo.flags
10135 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10136 // Services in peristent processes will restart much more
10137 // quickly, since they are pretty important. (Think SystemUI).
10138 r.restartDelay += minDuration/2;
10139 } else {
10140 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10141 if (r.restartDelay < minDuration) {
10142 r.restartDelay = minDuration;
10143 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010145 }
10146 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010147
10148 r.nextRestartTime = now + r.restartDelay;
10149
10150 // Make sure that we don't end up restarting a bunch of services
10151 // all at the same time.
10152 boolean repeat;
10153 do {
10154 repeat = false;
10155 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10156 ServiceRecord r2 = mRestartingServices.get(i);
10157 if (r2 != r && r.nextRestartTime
10158 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10159 && r.nextRestartTime
10160 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10161 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10162 r.restartDelay = r.nextRestartTime - now;
10163 repeat = true;
10164 break;
10165 }
10166 }
10167 } while (repeat);
10168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010169 if (!mRestartingServices.contains(r)) {
10170 mRestartingServices.add(r);
10171 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010172
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010173 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010175 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010176 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010177 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010178 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010179 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010180 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010181 r.shortName, r.restartDelay);
10182
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010183 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010184 }
10185
10186 final void performServiceRestartLocked(ServiceRecord r) {
10187 if (!mRestartingServices.contains(r)) {
10188 return;
10189 }
10190 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10191 }
10192
10193 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10194 if (r.restartDelay == 0) {
10195 return false;
10196 }
10197 r.resetRestartCounter();
10198 mRestartingServices.remove(r);
10199 mHandler.removeCallbacks(r.restarter);
10200 return true;
10201 }
10202
10203 private final boolean bringUpServiceLocked(ServiceRecord r,
10204 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010205 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010206 //r.dump(" ");
10207
Dianne Hackborn36124872009-10-08 16:22:03 -070010208 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010209 sendServiceArgsLocked(r, false);
10210 return true;
10211 }
10212
10213 if (!whileRestarting && r.restartDelay > 0) {
10214 // If waiting for a restart, then do nothing.
10215 return true;
10216 }
10217
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010218 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010220 // We are now bringing the service up, so no longer in the
10221 // restarting state.
10222 mRestartingServices.remove(r);
10223
Dianne Hackborne7f97212011-02-24 14:40:20 -080010224 // Service is now being launched, its package can't be stopped.
10225 try {
10226 AppGlobals.getPackageManager().setPackageStoppedState(
10227 r.packageName, false);
10228 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010229 } catch (IllegalArgumentException e) {
10230 Slog.w(TAG, "Failed trying to unstop package "
10231 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010232 }
10233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010234 final String appName = r.processName;
10235 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10236 if (app != null && app.thread != null) {
10237 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010238 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010239 realStartServiceLocked(r, app);
10240 return true;
10241 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010242 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010243 }
10244
10245 // If a dead object exception was thrown -- fall through to
10246 // restart the application.
10247 }
10248
Dianne Hackborn36124872009-10-08 16:22:03 -070010249 // Not running -- get it started, and enqueue this service record
10250 // to be executed when the app comes up.
10251 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10252 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010253 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010254 + r.appInfo.packageName + "/"
10255 + r.appInfo.uid + " for service "
10256 + r.intent.getIntent() + ": process is bad");
10257 bringDownServiceLocked(r, true);
10258 return false;
10259 }
10260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010261 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010262 mPendingServices.add(r);
10263 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010265 return true;
10266 }
10267
10268 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010269 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010270 //r.dump(" ");
10271
10272 // Does it still need to run?
10273 if (!force && r.startRequested) {
10274 return;
10275 }
10276 if (r.connections.size() > 0) {
10277 if (!force) {
10278 // XXX should probably keep a count of the number of auto-create
10279 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010280 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010281 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010282 ArrayList<ConnectionRecord> cr = it.next();
10283 for (int i=0; i<cr.size(); i++) {
10284 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10285 return;
10286 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010287 }
10288 }
10289 }
10290
10291 // Report to all of the connections that the service is no longer
10292 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010293 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010294 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010295 ArrayList<ConnectionRecord> c = it.next();
10296 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010297 ConnectionRecord cr = c.get(i);
10298 // There is still a connection to the service that is
10299 // being brought down. Mark it as dead.
10300 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010301 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010302 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010303 } catch (Exception e) {
10304 Slog.w(TAG, "Failure disconnecting service " + r.name +
10305 " to connection " + c.get(i).conn.asBinder() +
10306 " (in " + c.get(i).binding.client.processName + ")", e);
10307 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010308 }
10309 }
10310 }
10311
10312 // Tell the service that it has been unbound.
10313 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10314 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10315 while (it.hasNext()) {
10316 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010317 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010318 + ": hasBound=" + ibr.hasBound);
10319 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10320 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010321 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010322 updateOomAdjLocked(r.app);
10323 ibr.hasBound = false;
10324 r.app.thread.scheduleUnbindService(r,
10325 ibr.intent.getIntent());
10326 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010327 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010328 + r.shortName, e);
10329 serviceDoneExecutingLocked(r, true);
10330 }
10331 }
10332 }
10333 }
10334
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010335 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010336 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010337 System.identityHashCode(r), r.shortName,
10338 (r.app != null) ? r.app.pid : -1);
10339
10340 mServices.remove(r.name);
10341 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010342 r.totalRestartCount = 0;
10343 unscheduleServiceRestartLocked(r);
10344
10345 // Also make sure it is not on the pending list.
10346 int N = mPendingServices.size();
10347 for (int i=0; i<N; i++) {
10348 if (mPendingServices.get(i) == r) {
10349 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010350 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010351 i--;
10352 N--;
10353 }
10354 }
10355
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010356 r.cancelNotification();
10357 r.isForeground = false;
10358 r.foregroundId = 0;
10359 r.foregroundNoti = null;
10360
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010361 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010362 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010363 r.pendingStarts.clear();
10364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010365 if (r.app != null) {
10366 synchronized (r.stats.getBatteryStats()) {
10367 r.stats.stopLaunchedLocked();
10368 }
10369 r.app.services.remove(r);
10370 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010371 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010372 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010373 mStoppingServices.add(r);
10374 updateOomAdjLocked(r.app);
10375 r.app.thread.scheduleStopService(r);
10376 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010377 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010378 + r.shortName, e);
10379 serviceDoneExecutingLocked(r, true);
10380 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010381 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010382 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010383 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010384 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010385 }
10386 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010387 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010388 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010389 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010390
10391 if (r.bindings.size() > 0) {
10392 r.bindings.clear();
10393 }
10394
10395 if (r.restarter instanceof ServiceRestarter) {
10396 ((ServiceRestarter)r.restarter).setService(null);
10397 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010398 }
10399
10400 ComponentName startServiceLocked(IApplicationThread caller,
10401 Intent service, String resolvedType,
10402 int callingPid, int callingUid) {
10403 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010404 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010405 + " type=" + resolvedType + " args=" + service.getExtras());
10406
10407 if (caller != null) {
10408 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10409 if (callerApp == null) {
10410 throw new SecurityException(
10411 "Unable to find app for caller " + caller
10412 + " (pid=" + Binder.getCallingPid()
10413 + ") when starting service " + service);
10414 }
10415 }
10416
10417 ServiceLookupResult res =
10418 retrieveServiceLocked(service, resolvedType,
10419 callingPid, callingUid);
10420 if (res == null) {
10421 return null;
10422 }
10423 if (res.record == null) {
10424 return new ComponentName("!", res.permission != null
10425 ? res.permission : "private to package");
10426 }
10427 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010428 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10429 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010430 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010431 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010432 }
10433 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010434 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010435 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010436 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010437 r.lastActivity = SystemClock.uptimeMillis();
10438 synchronized (r.stats.getBatteryStats()) {
10439 r.stats.startRunningLocked();
10440 }
10441 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10442 return new ComponentName("!", "Service process is bad");
10443 }
10444 return r.name;
10445 }
10446 }
10447
10448 public ComponentName startService(IApplicationThread caller, Intent service,
10449 String resolvedType) {
10450 // Refuse possible leaked file descriptors
10451 if (service != null && service.hasFileDescriptors() == true) {
10452 throw new IllegalArgumentException("File descriptors passed in Intent");
10453 }
10454
10455 synchronized(this) {
10456 final int callingPid = Binder.getCallingPid();
10457 final int callingUid = Binder.getCallingUid();
10458 final long origId = Binder.clearCallingIdentity();
10459 ComponentName res = startServiceLocked(caller, service,
10460 resolvedType, callingPid, callingUid);
10461 Binder.restoreCallingIdentity(origId);
10462 return res;
10463 }
10464 }
10465
10466 ComponentName startServiceInPackage(int uid,
10467 Intent service, String resolvedType) {
10468 synchronized(this) {
10469 final long origId = Binder.clearCallingIdentity();
10470 ComponentName res = startServiceLocked(null, service,
10471 resolvedType, -1, uid);
10472 Binder.restoreCallingIdentity(origId);
10473 return res;
10474 }
10475 }
10476
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010477 private void stopServiceLocked(ServiceRecord service) {
10478 synchronized (service.stats.getBatteryStats()) {
10479 service.stats.stopRunningLocked();
10480 }
10481 service.startRequested = false;
10482 service.callStart = false;
10483 bringDownServiceLocked(service, false);
10484 }
10485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010486 public int stopService(IApplicationThread caller, Intent service,
10487 String resolvedType) {
10488 // Refuse possible leaked file descriptors
10489 if (service != null && service.hasFileDescriptors() == true) {
10490 throw new IllegalArgumentException("File descriptors passed in Intent");
10491 }
10492
10493 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010494 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010495 + " type=" + resolvedType);
10496
10497 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10498 if (caller != null && callerApp == null) {
10499 throw new SecurityException(
10500 "Unable to find app for caller " + caller
10501 + " (pid=" + Binder.getCallingPid()
10502 + ") when stopping service " + service);
10503 }
10504
10505 // If this service is active, make sure it is stopped.
10506 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10507 if (r != null) {
10508 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010509 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010510 try {
10511 stopServiceLocked(r.record);
10512 } finally {
10513 Binder.restoreCallingIdentity(origId);
10514 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010515 return 1;
10516 }
10517 return -1;
10518 }
10519 }
10520
10521 return 0;
10522 }
10523
10524 public IBinder peekService(Intent service, String resolvedType) {
10525 // Refuse possible leaked file descriptors
10526 if (service != null && service.hasFileDescriptors() == true) {
10527 throw new IllegalArgumentException("File descriptors passed in Intent");
10528 }
10529
10530 IBinder ret = null;
10531
10532 synchronized(this) {
10533 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10534
10535 if (r != null) {
10536 // r.record is null if findServiceLocked() failed the caller permission check
10537 if (r.record == null) {
10538 throw new SecurityException(
10539 "Permission Denial: Accessing service " + r.record.name
10540 + " from pid=" + Binder.getCallingPid()
10541 + ", uid=" + Binder.getCallingUid()
10542 + " requires " + r.permission);
10543 }
10544 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10545 if (ib != null) {
10546 ret = ib.binder;
10547 }
10548 }
10549 }
10550
10551 return ret;
10552 }
10553
10554 public boolean stopServiceToken(ComponentName className, IBinder token,
10555 int startId) {
10556 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010557 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010558 + " " + token + " startId=" + startId);
10559 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010560 if (r != null) {
10561 if (startId >= 0) {
10562 // Asked to only stop if done with all work. Note that
10563 // to avoid leaks, we will take this as dropping all
10564 // start items up to and including this one.
10565 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10566 if (si != null) {
10567 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010568 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10569 cur.removeUriPermissionsLocked();
10570 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010571 break;
10572 }
10573 }
10574 }
10575
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010576 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010577 return false;
10578 }
10579
10580 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010581 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010582 + " is last, but have " + r.deliveredStarts.size()
10583 + " remaining args");
10584 }
10585 }
10586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010587 synchronized (r.stats.getBatteryStats()) {
10588 r.stats.stopRunningLocked();
10589 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010590 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010591 }
10592 final long origId = Binder.clearCallingIdentity();
10593 bringDownServiceLocked(r, false);
10594 Binder.restoreCallingIdentity(origId);
10595 return true;
10596 }
10597 }
10598 return false;
10599 }
10600
10601 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010602 int id, Notification notification, boolean removeNotification) {
10603 final long origId = Binder.clearCallingIdentity();
10604 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010605 synchronized(this) {
10606 ServiceRecord r = findServiceLocked(className, token);
10607 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010608 if (id != 0) {
10609 if (notification == null) {
10610 throw new IllegalArgumentException("null notification");
10611 }
10612 if (r.foregroundId != id) {
10613 r.cancelNotification();
10614 r.foregroundId = id;
10615 }
10616 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10617 r.foregroundNoti = notification;
10618 r.isForeground = true;
10619 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010620 if (r.app != null) {
10621 updateServiceForegroundLocked(r.app, true);
10622 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010623 } else {
10624 if (r.isForeground) {
10625 r.isForeground = false;
10626 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010627 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010628 updateServiceForegroundLocked(r.app, true);
10629 }
10630 }
10631 if (removeNotification) {
10632 r.cancelNotification();
10633 r.foregroundId = 0;
10634 r.foregroundNoti = null;
10635 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010636 }
10637 }
10638 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010639 } finally {
10640 Binder.restoreCallingIdentity(origId);
10641 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010642 }
10643
10644 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10645 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010646 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010647 if (sr.isForeground) {
10648 anyForeground = true;
10649 break;
10650 }
10651 }
10652 if (anyForeground != proc.foregroundServices) {
10653 proc.foregroundServices = anyForeground;
10654 if (oomAdj) {
10655 updateOomAdjLocked();
10656 }
10657 }
10658 }
10659
10660 public int bindService(IApplicationThread caller, IBinder token,
10661 Intent service, String resolvedType,
10662 IServiceConnection connection, int flags) {
10663 // Refuse possible leaked file descriptors
10664 if (service != null && service.hasFileDescriptors() == true) {
10665 throw new IllegalArgumentException("File descriptors passed in Intent");
10666 }
10667
10668 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010669 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010670 + " type=" + resolvedType + " conn=" + connection.asBinder()
10671 + " flags=0x" + Integer.toHexString(flags));
10672 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10673 if (callerApp == null) {
10674 throw new SecurityException(
10675 "Unable to find app for caller " + caller
10676 + " (pid=" + Binder.getCallingPid()
10677 + ") when binding service " + service);
10678 }
10679
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010680 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010681 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010682 activity = mMainStack.isInStackLocked(token);
10683 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010684 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010685 return 0;
10686 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010687 }
10688
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010689 int clientLabel = 0;
10690 PendingIntent clientIntent = null;
10691
10692 if (callerApp.info.uid == Process.SYSTEM_UID) {
10693 // Hacky kind of thing -- allow system stuff to tell us
10694 // what they are, so we can report this elsewhere for
10695 // others to know why certain services are running.
10696 try {
10697 clientIntent = (PendingIntent)service.getParcelableExtra(
10698 Intent.EXTRA_CLIENT_INTENT);
10699 } catch (RuntimeException e) {
10700 }
10701 if (clientIntent != null) {
10702 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10703 if (clientLabel != 0) {
10704 // There are no useful extras in the intent, trash them.
10705 // System code calling with this stuff just needs to know
10706 // this will happen.
10707 service = service.cloneFilter();
10708 }
10709 }
10710 }
10711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010712 ServiceLookupResult res =
10713 retrieveServiceLocked(service, resolvedType,
10714 Binder.getCallingPid(), Binder.getCallingUid());
10715 if (res == null) {
10716 return 0;
10717 }
10718 if (res.record == null) {
10719 return -1;
10720 }
10721 ServiceRecord s = res.record;
10722
10723 final long origId = Binder.clearCallingIdentity();
10724
10725 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010726 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010727 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010728 }
10729
10730 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10731 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010732 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010733
10734 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010735 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10736 if (clist == null) {
10737 clist = new ArrayList<ConnectionRecord>();
10738 s.connections.put(binder, clist);
10739 }
10740 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010741 b.connections.add(c);
10742 if (activity != null) {
10743 if (activity.connections == null) {
10744 activity.connections = new HashSet<ConnectionRecord>();
10745 }
10746 activity.connections.add(c);
10747 }
10748 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010749 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10750 b.client.hasAboveClient = true;
10751 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010752 clist = mServiceConnections.get(binder);
10753 if (clist == null) {
10754 clist = new ArrayList<ConnectionRecord>();
10755 mServiceConnections.put(binder, clist);
10756 }
10757 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010758
10759 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10760 s.lastActivity = SystemClock.uptimeMillis();
10761 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10762 return 0;
10763 }
10764 }
10765
10766 if (s.app != null) {
10767 // This could have made the service more important.
10768 updateOomAdjLocked(s.app);
10769 }
10770
Joe Onorato8a9b2202010-02-26 18:56:32 -080010771 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010772 + ": received=" + b.intent.received
10773 + " apps=" + b.intent.apps.size()
10774 + " doRebind=" + b.intent.doRebind);
10775
10776 if (s.app != null && b.intent.received) {
10777 // Service is already running, so we can immediately
10778 // publish the connection.
10779 try {
10780 c.conn.connected(s.name, b.intent.binder);
10781 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010782 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010783 + " to connection " + c.conn.asBinder()
10784 + " (in " + c.binding.client.processName + ")", e);
10785 }
10786
10787 // If this is the first app connected back to this binding,
10788 // and the service had previously asked to be told when
10789 // rebound, then do so.
10790 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10791 requestServiceBindingLocked(s, b.intent, true);
10792 }
10793 } else if (!b.intent.requested) {
10794 requestServiceBindingLocked(s, b.intent, false);
10795 }
10796
10797 Binder.restoreCallingIdentity(origId);
10798 }
10799
10800 return 1;
10801 }
10802
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010803 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010804 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010805 IBinder binder = c.conn.asBinder();
10806 AppBindRecord b = c.binding;
10807 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010808 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10809 if (clist != null) {
10810 clist.remove(c);
10811 if (clist.size() == 0) {
10812 s.connections.remove(binder);
10813 }
10814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010815 b.connections.remove(c);
10816 if (c.activity != null && c.activity != skipAct) {
10817 if (c.activity.connections != null) {
10818 c.activity.connections.remove(c);
10819 }
10820 }
10821 if (b.client != skipApp) {
10822 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010823 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10824 b.client.updateHasAboveClientLocked();
10825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010826 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010827 clist = mServiceConnections.get(binder);
10828 if (clist != null) {
10829 clist.remove(c);
10830 if (clist.size() == 0) {
10831 mServiceConnections.remove(binder);
10832 }
10833 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010834
10835 if (b.connections.size() == 0) {
10836 b.intent.apps.remove(b.client);
10837 }
10838
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010839 if (!c.serviceDead) {
10840 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10841 + ": shouldUnbind=" + b.intent.hasBound);
10842 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10843 && b.intent.hasBound) {
10844 try {
10845 bumpServiceExecutingLocked(s, "unbind");
10846 updateOomAdjLocked(s.app);
10847 b.intent.hasBound = false;
10848 // Assume the client doesn't want to know about a rebind;
10849 // we will deal with that later if it asks for one.
10850 b.intent.doRebind = false;
10851 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10852 } catch (Exception e) {
10853 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10854 serviceDoneExecutingLocked(s, true);
10855 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010856 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010857
10858 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10859 bringDownServiceLocked(s, false);
10860 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010861 }
10862 }
10863
10864 public boolean unbindService(IServiceConnection connection) {
10865 synchronized (this) {
10866 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010867 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010868 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10869 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010870 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010871 + connection.asBinder());
10872 return false;
10873 }
10874
10875 final long origId = Binder.clearCallingIdentity();
10876
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010877 while (clist.size() > 0) {
10878 ConnectionRecord r = clist.get(0);
10879 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010880
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010881 if (r.binding.service.app != null) {
10882 // This could have made the service less important.
10883 updateOomAdjLocked(r.binding.service.app);
10884 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010885 }
10886
10887 Binder.restoreCallingIdentity(origId);
10888 }
10889
10890 return true;
10891 }
10892
10893 public void publishService(IBinder token, Intent intent, IBinder service) {
10894 // Refuse possible leaked file descriptors
10895 if (intent != null && intent.hasFileDescriptors() == true) {
10896 throw new IllegalArgumentException("File descriptors passed in Intent");
10897 }
10898
10899 synchronized(this) {
10900 if (!(token instanceof ServiceRecord)) {
10901 throw new IllegalArgumentException("Invalid service token");
10902 }
10903 ServiceRecord r = (ServiceRecord)token;
10904
10905 final long origId = Binder.clearCallingIdentity();
10906
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010907 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010908 + " " + intent + ": " + service);
10909 if (r != null) {
10910 Intent.FilterComparison filter
10911 = new Intent.FilterComparison(intent);
10912 IntentBindRecord b = r.bindings.get(filter);
10913 if (b != null && !b.received) {
10914 b.binder = service;
10915 b.requested = true;
10916 b.received = true;
10917 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010918 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010919 = r.connections.values().iterator();
10920 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010921 ArrayList<ConnectionRecord> clist = it.next();
10922 for (int i=0; i<clist.size(); i++) {
10923 ConnectionRecord c = clist.get(i);
10924 if (!filter.equals(c.binding.intent.intent)) {
10925 if (DEBUG_SERVICE) Slog.v(
10926 TAG, "Not publishing to: " + c);
10927 if (DEBUG_SERVICE) Slog.v(
10928 TAG, "Bound intent: " + c.binding.intent.intent);
10929 if (DEBUG_SERVICE) Slog.v(
10930 TAG, "Published intent: " + intent);
10931 continue;
10932 }
10933 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10934 try {
10935 c.conn.connected(r.name, service);
10936 } catch (Exception e) {
10937 Slog.w(TAG, "Failure sending service " + r.name +
10938 " to connection " + c.conn.asBinder() +
10939 " (in " + c.binding.client.processName + ")", e);
10940 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010941 }
10942 }
10943 }
10944 }
10945
10946 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10947
10948 Binder.restoreCallingIdentity(origId);
10949 }
10950 }
10951 }
10952
10953 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10954 // Refuse possible leaked file descriptors
10955 if (intent != null && intent.hasFileDescriptors() == true) {
10956 throw new IllegalArgumentException("File descriptors passed in Intent");
10957 }
10958
10959 synchronized(this) {
10960 if (!(token instanceof ServiceRecord)) {
10961 throw new IllegalArgumentException("Invalid service token");
10962 }
10963 ServiceRecord r = (ServiceRecord)token;
10964
10965 final long origId = Binder.clearCallingIdentity();
10966
10967 if (r != null) {
10968 Intent.FilterComparison filter
10969 = new Intent.FilterComparison(intent);
10970 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010971 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010972 + " at " + b + ": apps="
10973 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020010974
10975 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010976 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020010977 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010978 // Applications have already bound since the last
10979 // unbind, so just rebind right here.
10980 requestServiceBindingLocked(r, b, true);
10981 } else {
10982 // Note to tell the service the next time there is
10983 // a new client.
10984 b.doRebind = true;
10985 }
10986 }
10987
Per Edelberg78f9fff2010-08-30 20:01:35 +020010988 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010989
10990 Binder.restoreCallingIdentity(origId);
10991 }
10992 }
10993 }
10994
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010995 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010996 synchronized(this) {
10997 if (!(token instanceof ServiceRecord)) {
10998 throw new IllegalArgumentException("Invalid service token");
10999 }
11000 ServiceRecord r = (ServiceRecord)token;
11001 boolean inStopping = mStoppingServices.contains(token);
11002 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011003 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011004 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011005 + " with incorrect token: given " + token
11006 + ", expected " + r);
11007 return;
11008 }
11009
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011010 if (type == 1) {
11011 // This is a call from a service start... take care of
11012 // book-keeping.
11013 r.callStart = true;
11014 switch (res) {
11015 case Service.START_STICKY_COMPATIBILITY:
11016 case Service.START_STICKY: {
11017 // We are done with the associated start arguments.
11018 r.findDeliveredStart(startId, true);
11019 // Don't stop if killed.
11020 r.stopIfKilled = false;
11021 break;
11022 }
11023 case Service.START_NOT_STICKY: {
11024 // We are done with the associated start arguments.
11025 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011026 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011027 // There is no more work, and this service
11028 // doesn't want to hang around if killed.
11029 r.stopIfKilled = true;
11030 }
11031 break;
11032 }
11033 case Service.START_REDELIVER_INTENT: {
11034 // We'll keep this item until they explicitly
11035 // call stop for it, but keep track of the fact
11036 // that it was delivered.
11037 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11038 if (si != null) {
11039 si.deliveryCount = 0;
11040 si.doneExecutingCount++;
11041 // Don't stop if killed.
11042 r.stopIfKilled = true;
11043 }
11044 break;
11045 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011046 case Service.START_TASK_REMOVED_COMPLETE: {
11047 // Special processing for onTaskRemoved(). Don't
11048 // impact normal onStartCommand() processing.
11049 r.findDeliveredStart(startId, true);
11050 break;
11051 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011052 default:
11053 throw new IllegalArgumentException(
11054 "Unknown service start result: " + res);
11055 }
11056 if (res == Service.START_STICKY_COMPATIBILITY) {
11057 r.callStart = false;
11058 }
11059 }
11060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011061 final long origId = Binder.clearCallingIdentity();
11062 serviceDoneExecutingLocked(r, inStopping);
11063 Binder.restoreCallingIdentity(origId);
11064 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011065 Slog.w(TAG, "Done executing unknown service from pid "
11066 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011067 }
11068 }
11069 }
11070
11071 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011072 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11073 + ": nesting=" + r.executeNesting
11074 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011075 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011076 r.executeNesting--;
11077 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011078 if (DEBUG_SERVICE) Slog.v(TAG,
11079 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011080 r.app.executingServices.remove(r);
11081 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011082 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11083 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011084 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11085 }
11086 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011087 if (DEBUG_SERVICE) Slog.v(TAG,
11088 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011089 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011090 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011091 }
11092 updateOomAdjLocked(r.app);
11093 }
11094 }
11095
11096 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011097 String anrMessage = null;
11098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011099 synchronized(this) {
11100 if (proc.executingServices.size() == 0 || proc.thread == null) {
11101 return;
11102 }
11103 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11104 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11105 ServiceRecord timeout = null;
11106 long nextTime = 0;
11107 while (it.hasNext()) {
11108 ServiceRecord sr = it.next();
11109 if (sr.executingStart < maxTime) {
11110 timeout = sr;
11111 break;
11112 }
11113 if (sr.executingStart > nextTime) {
11114 nextTime = sr.executingStart;
11115 }
11116 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011117 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011118 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011119 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011120 } else {
11121 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11122 msg.obj = proc;
11123 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11124 }
11125 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011126
11127 if (anrMessage != null) {
11128 appNotResponding(proc, null, null, anrMessage);
11129 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011130 }
11131
11132 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011133 // BACKUP AND RESTORE
11134 // =========================================================
11135
11136 // Cause the target app to be launched if necessary and its backup agent
11137 // instantiated. The backup agent will invoke backupAgentCreated() on the
11138 // activity manager to announce its creation.
11139 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011140 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011141 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11142
11143 synchronized(this) {
11144 // !!! TODO: currently no check here that we're already bound
11145 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11146 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11147 synchronized (stats) {
11148 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11149 }
11150
Dianne Hackborne7f97212011-02-24 14:40:20 -080011151 // Backup agent is now in use, its package can't be stopped.
11152 try {
11153 AppGlobals.getPackageManager().setPackageStoppedState(
11154 app.packageName, false);
11155 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011156 } catch (IllegalArgumentException e) {
11157 Slog.w(TAG, "Failed trying to unstop package "
11158 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011159 }
11160
Christopher Tate181fafa2009-05-14 11:12:14 -070011161 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011162 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11163 ? new ComponentName(app.packageName, app.backupAgentName)
11164 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011165 // startProcessLocked() returns existing proc's record if it's already running
11166 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011167 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011168 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011169 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011170 return false;
11171 }
11172
11173 r.app = proc;
11174 mBackupTarget = r;
11175 mBackupAppName = app.packageName;
11176
Christopher Tate6fa95972009-06-05 18:43:55 -070011177 // Try not to kill the process during backup
11178 updateOomAdjLocked(proc);
11179
Christopher Tate181fafa2009-05-14 11:12:14 -070011180 // If the process is already attached, schedule the creation of the backup agent now.
11181 // If it is not yet live, this will be done when it attaches to the framework.
11182 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011183 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011184 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011185 proc.thread.scheduleCreateBackupAgent(app,
11186 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011187 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011188 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011189 }
11190 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011191 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011192 }
11193 // Invariants: at this point, the target app process exists and the application
11194 // is either already running or in the process of coming up. mBackupTarget and
11195 // mBackupAppName describe the app, so that when it binds back to the AM we
11196 // know that it's scheduled for a backup-agent operation.
11197 }
11198
11199 return true;
11200 }
11201
11202 // A backup agent has just come up
11203 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011204 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011205 + " = " + agent);
11206
11207 synchronized(this) {
11208 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011209 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011210 return;
11211 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011212 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011213
Dianne Hackborn06740692010-09-22 22:46:21 -070011214 long oldIdent = Binder.clearCallingIdentity();
11215 try {
11216 IBackupManager bm = IBackupManager.Stub.asInterface(
11217 ServiceManager.getService(Context.BACKUP_SERVICE));
11218 bm.agentConnected(agentPackageName, agent);
11219 } catch (RemoteException e) {
11220 // can't happen; the backup manager service is local
11221 } catch (Exception e) {
11222 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11223 e.printStackTrace();
11224 } finally {
11225 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011226 }
11227 }
11228
11229 // done with this agent
11230 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011231 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011232 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011233 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011234 return;
11235 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011236
11237 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011238 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011239 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011240 return;
11241 }
11242
Christopher Tate181fafa2009-05-14 11:12:14 -070011243 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011244 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011245 return;
11246 }
11247
Christopher Tate6fa95972009-06-05 18:43:55 -070011248 ProcessRecord proc = mBackupTarget.app;
11249 mBackupTarget = null;
11250 mBackupAppName = null;
11251
11252 // Not backing this app up any more; reset its OOM adjustment
11253 updateOomAdjLocked(proc);
11254
Christopher Tatec7b31e32009-06-10 15:49:30 -070011255 // If the app crashed during backup, 'thread' will be null here
11256 if (proc.thread != null) {
11257 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011258 proc.thread.scheduleDestroyBackupAgent(appInfo,
11259 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011260 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011261 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011262 e.printStackTrace();
11263 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011264 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011265 }
11266 }
11267 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011268 // BROADCASTS
11269 // =========================================================
11270
Josh Bartel7f208742010-02-25 11:01:44 -060011271 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011272 List cur) {
11273 final ContentResolver resolver = mContext.getContentResolver();
11274 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11275 if (list == null) {
11276 return cur;
11277 }
11278 int N = list.size();
11279 for (int i=0; i<N; i++) {
11280 Intent intent = list.get(i);
11281 if (filter.match(resolver, intent, true, TAG) >= 0) {
11282 if (cur == null) {
11283 cur = new ArrayList<Intent>();
11284 }
11285 cur.add(intent);
11286 }
11287 }
11288 return cur;
11289 }
11290
11291 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011292 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011293 + mBroadcastsScheduled);
11294
11295 if (mBroadcastsScheduled) {
11296 return;
11297 }
11298 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11299 mBroadcastsScheduled = true;
11300 }
11301
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011302 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011303 IIntentReceiver receiver, IntentFilter filter, String permission) {
11304 synchronized(this) {
11305 ProcessRecord callerApp = null;
11306 if (caller != null) {
11307 callerApp = getRecordForAppLocked(caller);
11308 if (callerApp == null) {
11309 throw new SecurityException(
11310 "Unable to find app for caller " + caller
11311 + " (pid=" + Binder.getCallingPid()
11312 + ") when registering receiver " + receiver);
11313 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011314 if (callerApp.info.uid != Process.SYSTEM_UID &&
11315 !callerApp.pkgList.contains(callerPackage)) {
11316 throw new SecurityException("Given caller package " + callerPackage
11317 + " is not running in process " + callerApp);
11318 }
11319 } else {
11320 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011321 }
11322
11323 List allSticky = null;
11324
11325 // Look for any matching sticky broadcasts...
11326 Iterator actions = filter.actionsIterator();
11327 if (actions != null) {
11328 while (actions.hasNext()) {
11329 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011330 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011331 }
11332 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011333 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011334 }
11335
11336 // The first sticky in the list is returned directly back to
11337 // the client.
11338 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11339
Joe Onorato8a9b2202010-02-26 18:56:32 -080011340 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011341 + ": " + sticky);
11342
11343 if (receiver == null) {
11344 return sticky;
11345 }
11346
11347 ReceiverList rl
11348 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11349 if (rl == null) {
11350 rl = new ReceiverList(this, callerApp,
11351 Binder.getCallingPid(),
11352 Binder.getCallingUid(), receiver);
11353 if (rl.app != null) {
11354 rl.app.receivers.add(rl);
11355 } else {
11356 try {
11357 receiver.asBinder().linkToDeath(rl, 0);
11358 } catch (RemoteException e) {
11359 return sticky;
11360 }
11361 rl.linkedToDeath = true;
11362 }
11363 mRegisteredReceivers.put(receiver.asBinder(), rl);
11364 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011365 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011366 rl.add(bf);
11367 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011368 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011369 }
11370 mReceiverResolver.addFilter(bf);
11371
11372 // Enqueue broadcasts for all existing stickies that match
11373 // this filter.
11374 if (allSticky != null) {
11375 ArrayList receivers = new ArrayList();
11376 receivers.add(bf);
11377
11378 int N = allSticky.size();
11379 for (int i=0; i<N; i++) {
11380 Intent intent = (Intent)allSticky.get(i);
11381 BroadcastRecord r = new BroadcastRecord(intent, null,
11382 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011383 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011384 if (mParallelBroadcasts.size() == 0) {
11385 scheduleBroadcastsLocked();
11386 }
11387 mParallelBroadcasts.add(r);
11388 }
11389 }
11390
11391 return sticky;
11392 }
11393 }
11394
11395 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011396 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011397
11398 boolean doNext = false;
11399
11400 synchronized(this) {
11401 ReceiverList rl
11402 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11403 if (rl != null) {
11404 if (rl.curBroadcast != null) {
11405 BroadcastRecord r = rl.curBroadcast;
11406 doNext = finishReceiverLocked(
11407 receiver.asBinder(), r.resultCode, r.resultData,
11408 r.resultExtras, r.resultAbort, true);
11409 }
11410
11411 if (rl.app != null) {
11412 rl.app.receivers.remove(rl);
11413 }
11414 removeReceiverLocked(rl);
11415 if (rl.linkedToDeath) {
11416 rl.linkedToDeath = false;
11417 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11418 }
11419 }
11420 }
11421
11422 if (!doNext) {
11423 return;
11424 }
11425
11426 final long origId = Binder.clearCallingIdentity();
11427 processNextBroadcast(false);
11428 trimApplications();
11429 Binder.restoreCallingIdentity(origId);
11430 }
11431
11432 void removeReceiverLocked(ReceiverList rl) {
11433 mRegisteredReceivers.remove(rl.receiver.asBinder());
11434 int N = rl.size();
11435 for (int i=0; i<N; i++) {
11436 mReceiverResolver.removeFilter(rl.get(i));
11437 }
11438 }
11439
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011440 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11441 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11442 ProcessRecord r = mLruProcesses.get(i);
11443 if (r.thread != null) {
11444 try {
11445 r.thread.dispatchPackageBroadcast(cmd, packages);
11446 } catch (RemoteException ex) {
11447 }
11448 }
11449 }
11450 }
11451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011452 private final int broadcastIntentLocked(ProcessRecord callerApp,
11453 String callerPackage, Intent intent, String resolvedType,
11454 IIntentReceiver resultTo, int resultCode, String resultData,
11455 Bundle map, String requiredPermission,
11456 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11457 intent = new Intent(intent);
11458
Dianne Hackborne7f97212011-02-24 14:40:20 -080011459 // By default broadcasts do not go to stopped apps.
11460 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11461
Joe Onorato8a9b2202010-02-26 18:56:32 -080011462 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011463 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11464 + " ordered=" + ordered);
11465 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011466 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011467 }
11468
11469 // Handle special intents: if this broadcast is from the package
11470 // manager about a package being removed, we need to remove all of
11471 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011472 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011473 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011474 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11475 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011476 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011477 || uidRemoved) {
11478 if (checkComponentPermission(
11479 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011480 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011481 == PackageManager.PERMISSION_GRANTED) {
11482 if (uidRemoved) {
11483 final Bundle intentExtras = intent.getExtras();
11484 final int uid = intentExtras != null
11485 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11486 if (uid >= 0) {
11487 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11488 synchronized (bs) {
11489 bs.removeUidStatsLocked(uid);
11490 }
11491 }
11492 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011493 // If resources are unvailble just force stop all
11494 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011495 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011496 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11497 if (list != null && (list.length > 0)) {
11498 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011499 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011500 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011501 sendPackageBroadcastLocked(
11502 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011503 }
11504 } else {
11505 Uri data = intent.getData();
11506 String ssp;
11507 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11508 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11509 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011510 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011511 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011512 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011513 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11514 new String[] {ssp});
11515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011516 }
11517 }
11518 }
11519 } else {
11520 String msg = "Permission Denial: " + intent.getAction()
11521 + " broadcast from " + callerPackage + " (pid=" + callingPid
11522 + ", uid=" + callingUid + ")"
11523 + " requires "
11524 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011525 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011526 throw new SecurityException(msg);
11527 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011528
11529 // Special case for adding a package: by default turn on compatibility
11530 // mode.
11531 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011532 Uri data = intent.getData();
11533 String ssp;
11534 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11535 mCompatModePackages.handlePackageAddedLocked(ssp,
11536 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011538 }
11539
11540 /*
11541 * If this is the time zone changed action, queue up a message that will reset the timezone
11542 * of all currently running processes. This message will get queued up before the broadcast
11543 * happens.
11544 */
11545 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11546 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11547 }
11548
Robert Greenwalt03595d02010-11-02 14:08:23 -070011549 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11550 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11551 }
11552
Robert Greenwalt434203a2010-10-11 16:00:27 -070011553 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11554 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11555 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11556 }
11557
Dianne Hackborn854060af2009-07-09 18:14:31 -070011558 /*
11559 * Prevent non-system code (defined here to be non-persistent
11560 * processes) from sending protected broadcasts.
11561 */
11562 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11563 || callingUid == Process.SHELL_UID || callingUid == 0) {
11564 // Always okay.
11565 } else if (callerApp == null || !callerApp.persistent) {
11566 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011567 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011568 intent.getAction())) {
11569 String msg = "Permission Denial: not allowed to send broadcast "
11570 + intent.getAction() + " from pid="
11571 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011572 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011573 throw new SecurityException(msg);
11574 }
11575 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011576 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011577 return BROADCAST_SUCCESS;
11578 }
11579 }
11580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011581 // Add to the sticky list if requested.
11582 if (sticky) {
11583 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11584 callingPid, callingUid)
11585 != PackageManager.PERMISSION_GRANTED) {
11586 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11587 + callingPid + ", uid=" + callingUid
11588 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011589 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011590 throw new SecurityException(msg);
11591 }
11592 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011593 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011594 + " and enforce permission " + requiredPermission);
11595 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11596 }
11597 if (intent.getComponent() != null) {
11598 throw new SecurityException(
11599 "Sticky broadcasts can't target a specific component");
11600 }
11601 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11602 if (list == null) {
11603 list = new ArrayList<Intent>();
11604 mStickyBroadcasts.put(intent.getAction(), list);
11605 }
11606 int N = list.size();
11607 int i;
11608 for (i=0; i<N; i++) {
11609 if (intent.filterEquals(list.get(i))) {
11610 // This sticky already exists, replace it.
11611 list.set(i, new Intent(intent));
11612 break;
11613 }
11614 }
11615 if (i >= N) {
11616 list.add(new Intent(intent));
11617 }
11618 }
11619
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011620 // Figure out who all will receive this broadcast.
11621 List receivers = null;
11622 List<BroadcastFilter> registeredReceivers = null;
11623 try {
11624 if (intent.getComponent() != null) {
11625 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011626 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011627 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011628 if (ai != null) {
11629 receivers = new ArrayList();
11630 ResolveInfo ri = new ResolveInfo();
11631 ri.activityInfo = ai;
11632 receivers.add(ri);
11633 }
11634 } else {
11635 // Need to resolve the intent to interested receivers...
11636 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11637 == 0) {
11638 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011639 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011640 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011641 }
Mihai Preda074edef2009-05-18 17:13:31 +020011642 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011643 }
11644 } catch (RemoteException ex) {
11645 // pm is in same process, this will never happen.
11646 }
11647
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011648 final boolean replacePending =
11649 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11650
Joe Onorato8a9b2202010-02-26 18:56:32 -080011651 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011652 + " replacePending=" + replacePending);
11653
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011654 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11655 if (!ordered && NR > 0) {
11656 // If we are not serializing this broadcast, then send the
11657 // registered receivers separately so they don't wait for the
11658 // components to be launched.
11659 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11660 callerPackage, callingPid, callingUid, requiredPermission,
11661 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011662 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011663 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011664 TAG, "Enqueueing parallel broadcast " + r
11665 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011666 boolean replaced = false;
11667 if (replacePending) {
11668 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11669 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011670 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011671 "***** DROPPING PARALLEL: " + intent);
11672 mParallelBroadcasts.set(i, r);
11673 replaced = true;
11674 break;
11675 }
11676 }
11677 }
11678 if (!replaced) {
11679 mParallelBroadcasts.add(r);
11680 scheduleBroadcastsLocked();
11681 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011682 registeredReceivers = null;
11683 NR = 0;
11684 }
11685
11686 // Merge into one list.
11687 int ir = 0;
11688 if (receivers != null) {
11689 // A special case for PACKAGE_ADDED: do not allow the package
11690 // being added to see this broadcast. This prevents them from
11691 // using this as a back door to get run as soon as they are
11692 // installed. Maybe in the future we want to have a special install
11693 // broadcast or such for apps, but we'd like to deliberately make
11694 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011695 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011696 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11697 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11698 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011699 Uri data = intent.getData();
11700 if (data != null) {
11701 String pkgName = data.getSchemeSpecificPart();
11702 if (pkgName != null) {
11703 skipPackages = new String[] { pkgName };
11704 }
11705 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011706 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011707 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011708 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011709 if (skipPackages != null && (skipPackages.length > 0)) {
11710 for (String skipPackage : skipPackages) {
11711 if (skipPackage != null) {
11712 int NT = receivers.size();
11713 for (int it=0; it<NT; it++) {
11714 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11715 if (curt.activityInfo.packageName.equals(skipPackage)) {
11716 receivers.remove(it);
11717 it--;
11718 NT--;
11719 }
11720 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011721 }
11722 }
11723 }
11724
11725 int NT = receivers != null ? receivers.size() : 0;
11726 int it = 0;
11727 ResolveInfo curt = null;
11728 BroadcastFilter curr = null;
11729 while (it < NT && ir < NR) {
11730 if (curt == null) {
11731 curt = (ResolveInfo)receivers.get(it);
11732 }
11733 if (curr == null) {
11734 curr = registeredReceivers.get(ir);
11735 }
11736 if (curr.getPriority() >= curt.priority) {
11737 // Insert this broadcast record into the final list.
11738 receivers.add(it, curr);
11739 ir++;
11740 curr = null;
11741 it++;
11742 NT++;
11743 } else {
11744 // Skip to the next ResolveInfo in the final list.
11745 it++;
11746 curt = null;
11747 }
11748 }
11749 }
11750 while (ir < NR) {
11751 if (receivers == null) {
11752 receivers = new ArrayList();
11753 }
11754 receivers.add(registeredReceivers.get(ir));
11755 ir++;
11756 }
11757
11758 if ((receivers != null && receivers.size() > 0)
11759 || resultTo != null) {
11760 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11761 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011762 receivers, resultTo, resultCode, resultData, map, ordered,
11763 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011764 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011765 TAG, "Enqueueing ordered broadcast " + r
11766 + ": prev had " + mOrderedBroadcasts.size());
11767 if (DEBUG_BROADCAST) {
11768 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011769 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011770 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011771 boolean replaced = false;
11772 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011773 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011774 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011775 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011776 "***** DROPPING ORDERED: " + intent);
11777 mOrderedBroadcasts.set(i, r);
11778 replaced = true;
11779 break;
11780 }
11781 }
11782 }
11783 if (!replaced) {
11784 mOrderedBroadcasts.add(r);
11785 scheduleBroadcastsLocked();
11786 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011787 }
11788
11789 return BROADCAST_SUCCESS;
11790 }
11791
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011792 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011793 // Refuse possible leaked file descriptors
11794 if (intent != null && intent.hasFileDescriptors() == true) {
11795 throw new IllegalArgumentException("File descriptors passed in Intent");
11796 }
11797
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011798 int flags = intent.getFlags();
11799
11800 if (!mProcessesReady) {
11801 // if the caller really truly claims to know what they're doing, go
11802 // ahead and allow the broadcast without launching any receivers
11803 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11804 intent = new Intent(intent);
11805 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11806 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11807 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11808 + " before boot completion");
11809 throw new IllegalStateException("Cannot broadcast before boot completed");
11810 }
11811 }
11812
11813 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11814 throw new IllegalArgumentException(
11815 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11816 }
11817
11818 return intent;
11819 }
11820
11821 public final int broadcastIntent(IApplicationThread caller,
11822 Intent intent, String resolvedType, IIntentReceiver resultTo,
11823 int resultCode, String resultData, Bundle map,
11824 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011825 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011826 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011828 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11829 final int callingPid = Binder.getCallingPid();
11830 final int callingUid = Binder.getCallingUid();
11831 final long origId = Binder.clearCallingIdentity();
11832 int res = broadcastIntentLocked(callerApp,
11833 callerApp != null ? callerApp.info.packageName : null,
11834 intent, resolvedType, resultTo,
11835 resultCode, resultData, map, requiredPermission, serialized,
11836 sticky, callingPid, callingUid);
11837 Binder.restoreCallingIdentity(origId);
11838 return res;
11839 }
11840 }
11841
11842 int broadcastIntentInPackage(String packageName, int uid,
11843 Intent intent, String resolvedType, IIntentReceiver resultTo,
11844 int resultCode, String resultData, Bundle map,
11845 String requiredPermission, boolean serialized, boolean sticky) {
11846 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011847 intent = verifyBroadcastLocked(intent);
11848
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011849 final long origId = Binder.clearCallingIdentity();
11850 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11851 resultTo, resultCode, resultData, map, requiredPermission,
11852 serialized, sticky, -1, uid);
11853 Binder.restoreCallingIdentity(origId);
11854 return res;
11855 }
11856 }
11857
11858 public final void unbroadcastIntent(IApplicationThread caller,
11859 Intent intent) {
11860 // Refuse possible leaked file descriptors
11861 if (intent != null && intent.hasFileDescriptors() == true) {
11862 throw new IllegalArgumentException("File descriptors passed in Intent");
11863 }
11864
11865 synchronized(this) {
11866 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11867 != PackageManager.PERMISSION_GRANTED) {
11868 String msg = "Permission Denial: unbroadcastIntent() from pid="
11869 + Binder.getCallingPid()
11870 + ", uid=" + Binder.getCallingUid()
11871 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011872 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011873 throw new SecurityException(msg);
11874 }
11875 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11876 if (list != null) {
11877 int N = list.size();
11878 int i;
11879 for (i=0; i<N; i++) {
11880 if (intent.filterEquals(list.get(i))) {
11881 list.remove(i);
11882 break;
11883 }
11884 }
11885 }
11886 }
11887 }
11888
11889 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11890 String resultData, Bundle resultExtras, boolean resultAbort,
11891 boolean explicit) {
11892 if (mOrderedBroadcasts.size() == 0) {
11893 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011894 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011895 }
11896 return false;
11897 }
11898 BroadcastRecord r = mOrderedBroadcasts.get(0);
11899 if (r.receiver == null) {
11900 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011901 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011902 }
11903 return false;
11904 }
11905 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011906 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011907 return false;
11908 }
11909 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011910 r.state = BroadcastRecord.IDLE;
11911 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011912 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011913 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011914 }
11915 }
11916 r.receiver = null;
11917 r.intent.setComponent(null);
11918 if (r.curApp != null) {
11919 r.curApp.curReceiver = null;
11920 }
11921 if (r.curFilter != null) {
11922 r.curFilter.receiverList.curBroadcast = null;
11923 }
11924 r.curFilter = null;
11925 r.curApp = null;
11926 r.curComponent = null;
11927 r.curReceiver = null;
11928 mPendingBroadcast = null;
11929
11930 r.resultCode = resultCode;
11931 r.resultData = resultData;
11932 r.resultExtras = resultExtras;
11933 r.resultAbort = resultAbort;
11934
11935 // We will process the next receiver right now if this is finishing
11936 // an app receiver (which is always asynchronous) or after we have
11937 // come back from calling a receiver.
11938 return state == BroadcastRecord.APP_RECEIVE
11939 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11940 }
11941
11942 public void finishReceiver(IBinder who, int resultCode, String resultData,
11943 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011944 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011945
11946 // Refuse possible leaked file descriptors
11947 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11948 throw new IllegalArgumentException("File descriptors passed in Bundle");
11949 }
11950
11951 boolean doNext;
11952
11953 final long origId = Binder.clearCallingIdentity();
11954
11955 synchronized(this) {
11956 doNext = finishReceiverLocked(
11957 who, resultCode, resultData, resultExtras, resultAbort, true);
11958 }
11959
11960 if (doNext) {
11961 processNextBroadcast(false);
11962 }
11963 trimApplications();
11964
11965 Binder.restoreCallingIdentity(origId);
11966 }
11967
Jeff Brown4d94a762010-09-23 11:33:28 -070011968 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011969 if (r.nextReceiver > 0) {
11970 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11971 if (curReceiver instanceof BroadcastFilter) {
11972 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011973 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011974 System.identityHashCode(r),
11975 r.intent.getAction(),
11976 r.nextReceiver - 1,
11977 System.identityHashCode(bf));
11978 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011979 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011980 System.identityHashCode(r),
11981 r.intent.getAction(),
11982 r.nextReceiver - 1,
11983 ((ResolveInfo)curReceiver).toString());
11984 }
11985 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011986 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011987 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011988 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011989 System.identityHashCode(r),
11990 r.intent.getAction(),
11991 r.nextReceiver,
11992 "NONE");
11993 }
11994 }
11995
Jeff Brown4d94a762010-09-23 11:33:28 -070011996 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11997 if (! mPendingBroadcastTimeoutMessage) {
11998 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11999 mHandler.sendMessageAtTime(msg, timeoutTime);
12000 mPendingBroadcastTimeoutMessage = true;
12001 }
12002 }
12003
12004 private final void cancelBroadcastTimeoutLocked() {
12005 if (mPendingBroadcastTimeoutMessage) {
12006 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12007 mPendingBroadcastTimeoutMessage = false;
12008 }
12009 }
12010
12011 private final void broadcastTimeoutLocked(boolean fromMsg) {
12012 if (fromMsg) {
12013 mPendingBroadcastTimeoutMessage = false;
12014 }
12015
12016 if (mOrderedBroadcasts.size() == 0) {
12017 return;
12018 }
12019
12020 long now = SystemClock.uptimeMillis();
12021 BroadcastRecord r = mOrderedBroadcasts.get(0);
12022 if (fromMsg) {
12023 if (mDidDexOpt) {
12024 // Delay timeouts until dexopt finishes.
12025 mDidDexOpt = false;
12026 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12027 setBroadcastTimeoutLocked(timeoutTime);
12028 return;
12029 }
12030 if (! mProcessesReady) {
12031 // Only process broadcast timeouts if the system is ready. That way
12032 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12033 // to do heavy lifting for system up.
12034 return;
12035 }
12036
12037 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12038 if (timeoutTime > now) {
12039 // We can observe premature timeouts because we do not cancel and reset the
12040 // broadcast timeout message after each receiver finishes. Instead, we set up
12041 // an initial timeout then kick it down the road a little further as needed
12042 // when it expires.
12043 if (DEBUG_BROADCAST) Slog.v(TAG,
12044 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12045 + timeoutTime);
12046 setBroadcastTimeoutLocked(timeoutTime);
12047 return;
12048 }
12049 }
12050
12051 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12052 + ", started " + (now - r.receiverTime) + "ms ago");
12053 r.receiverTime = now;
12054 r.anrCount++;
12055
12056 // Current receiver has passed its expiration date.
12057 if (r.nextReceiver <= 0) {
12058 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12059 return;
12060 }
12061
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012062 ProcessRecord app = null;
12063 String anrMessage = null;
12064
Jeff Brown4d94a762010-09-23 11:33:28 -070012065 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12066 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12067 logBroadcastReceiverDiscardLocked(r);
12068 if (curReceiver instanceof BroadcastFilter) {
12069 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12070 if (bf.receiverList.pid != 0
12071 && bf.receiverList.pid != MY_PID) {
12072 synchronized (this.mPidsSelfLocked) {
12073 app = this.mPidsSelfLocked.get(
12074 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012075 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012076 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012077 } else {
12078 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012079 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012080
Jeff Brown4d94a762010-09-23 11:33:28 -070012081 if (app != null) {
12082 anrMessage = "Broadcast of " + r.intent.toString();
12083 }
12084
12085 if (mPendingBroadcast == r) {
12086 mPendingBroadcast = null;
12087 }
12088
12089 // Move on to the next receiver.
12090 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12091 r.resultExtras, r.resultAbort, true);
12092 scheduleBroadcastsLocked();
12093
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012094 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012095 // Post the ANR to the handler since we do not want to process ANRs while
12096 // potentially holding our lock.
12097 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012098 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012099 }
12100
12101 private final void processCurBroadcastLocked(BroadcastRecord r,
12102 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012103 if (DEBUG_BROADCAST) Slog.v(TAG,
12104 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012105 if (app.thread == null) {
12106 throw new RemoteException();
12107 }
12108 r.receiver = app.thread.asBinder();
12109 r.curApp = app;
12110 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012111 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012112
12113 // Tell the application to launch this receiver.
12114 r.intent.setComponent(r.curComponent);
12115
12116 boolean started = false;
12117 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012118 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012119 "Delivering to component " + r.curComponent
12120 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012121 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012122 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012123 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012124 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012125 if (DEBUG_BROADCAST) Slog.v(TAG,
12126 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012127 started = true;
12128 } finally {
12129 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012130 if (DEBUG_BROADCAST) Slog.v(TAG,
12131 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012132 r.receiver = null;
12133 r.curApp = null;
12134 app.curReceiver = null;
12135 }
12136 }
12137
12138 }
12139
Jeff Brown4d94a762010-09-23 11:33:28 -070012140 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012141 Intent intent, int resultCode, String data, Bundle extras,
12142 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012143 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012144 if (app != null && app.thread != null) {
12145 // If we have an app thread, do the call through that so it is
12146 // correctly ordered with other one-way calls.
12147 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012148 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012149 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012150 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012151 }
12152 }
12153
Jeff Brown4d94a762010-09-23 11:33:28 -070012154 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012155 BroadcastFilter filter, boolean ordered) {
12156 boolean skip = false;
12157 if (filter.requiredPermission != null) {
12158 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012159 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012160 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012161 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012162 + r.intent.toString()
12163 + " from " + r.callerPackage + " (pid="
12164 + r.callingPid + ", uid=" + r.callingUid + ")"
12165 + " requires " + filter.requiredPermission
12166 + " due to registered receiver " + filter);
12167 skip = true;
12168 }
12169 }
12170 if (r.requiredPermission != null) {
12171 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012172 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012173 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012174 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012175 + r.intent.toString()
12176 + " to " + filter.receiverList.app
12177 + " (pid=" + filter.receiverList.pid
12178 + ", uid=" + filter.receiverList.uid + ")"
12179 + " requires " + r.requiredPermission
12180 + " due to sender " + r.callerPackage
12181 + " (uid " + r.callingUid + ")");
12182 skip = true;
12183 }
12184 }
12185
12186 if (!skip) {
12187 // If this is not being sent as an ordered broadcast, then we
12188 // don't want to touch the fields that keep track of the current
12189 // state of ordered broadcasts.
12190 if (ordered) {
12191 r.receiver = filter.receiverList.receiver.asBinder();
12192 r.curFilter = filter;
12193 filter.receiverList.curBroadcast = r;
12194 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012195 if (filter.receiverList.app != null) {
12196 // Bump hosting application to no longer be in background
12197 // scheduling class. Note that we can't do that if there
12198 // isn't an app... but we can only be in that case for
12199 // things that directly call the IActivityManager API, which
12200 // are already core system stuff so don't matter for this.
12201 r.curApp = filter.receiverList.app;
12202 filter.receiverList.app.curReceiver = r;
12203 updateOomAdjLocked();
12204 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012205 }
12206 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012207 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012208 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012209 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012210 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012211 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012212 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012213 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012214 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012215 if (ordered) {
12216 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12217 }
12218 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012219 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012220 if (ordered) {
12221 r.receiver = null;
12222 r.curFilter = null;
12223 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012224 if (filter.receiverList.app != null) {
12225 filter.receiverList.app.curReceiver = null;
12226 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012227 }
12228 }
12229 }
12230 }
12231
Dianne Hackborn12527f92009-11-11 17:39:50 -080012232 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12233 if (r.callingUid < 0) {
12234 // This was from a registerReceiver() call; ignore it.
12235 return;
12236 }
12237 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12238 MAX_BROADCAST_HISTORY-1);
12239 r.finishTime = SystemClock.uptimeMillis();
12240 mBroadcastHistory[0] = r;
12241 }
12242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012243 private final void processNextBroadcast(boolean fromMsg) {
12244 synchronized(this) {
12245 BroadcastRecord r;
12246
Joe Onorato8a9b2202010-02-26 18:56:32 -080012247 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012248 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012249 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012250
12251 updateCpuStats();
12252
12253 if (fromMsg) {
12254 mBroadcastsScheduled = false;
12255 }
12256
12257 // First, deliver any non-serialized broadcasts right away.
12258 while (mParallelBroadcasts.size() > 0) {
12259 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012260 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012261 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012262 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012263 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012264 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012265 for (int i=0; i<N; i++) {
12266 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012267 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012268 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012269 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012270 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012271 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012272 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012273 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012274 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012275 }
12276
12277 // Now take care of the next serialized one...
12278
12279 // If we are waiting for a process to come up to handle the next
12280 // broadcast, then do nothing at this point. Just in case, we
12281 // check that the process we're waiting for still exists.
12282 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012283 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012284 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012285 + mPendingBroadcast.curApp);
12286 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012287
12288 boolean isDead;
12289 synchronized (mPidsSelfLocked) {
12290 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12291 }
12292 if (!isDead) {
12293 // It's still alive, so keep waiting
12294 return;
12295 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012296 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012297 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012298 mPendingBroadcast.state = BroadcastRecord.IDLE;
12299 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012300 mPendingBroadcast = null;
12301 }
12302 }
12303
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012304 boolean looped = false;
12305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012306 do {
12307 if (mOrderedBroadcasts.size() == 0) {
12308 // No more broadcasts pending, so all done!
12309 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012310 if (looped) {
12311 // If we had finished the last ordered broadcast, then
12312 // make sure all processes have correct oom and sched
12313 // adjustments.
12314 updateOomAdjLocked();
12315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012316 return;
12317 }
12318 r = mOrderedBroadcasts.get(0);
12319 boolean forceReceive = false;
12320
12321 // Ensure that even if something goes awry with the timeout
12322 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012323 // and continue to make progress.
12324 //
12325 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012326 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012327 // one time heavy lifting after system upgrades and can take
12328 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012329 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012330 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012331 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012332 if ((numReceivers > 0) &&
12333 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012334 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012335 + " now=" + now
12336 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012337 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012338 + " intent=" + r.intent
12339 + " numReceivers=" + numReceivers
12340 + " nextReceiver=" + r.nextReceiver
12341 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012342 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012343 forceReceive = true;
12344 r.state = BroadcastRecord.IDLE;
12345 }
12346 }
12347
12348 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012349 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012350 "processNextBroadcast() called when not idle (state="
12351 + r.state + ")");
12352 return;
12353 }
12354
12355 if (r.receivers == null || r.nextReceiver >= numReceivers
12356 || r.resultAbort || forceReceive) {
12357 // No more receivers for this broadcast! Send the final
12358 // result if requested...
12359 if (r.resultTo != null) {
12360 try {
12361 if (DEBUG_BROADCAST) {
12362 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012363 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012364 + " seq=" + seq + " app=" + r.callerApp);
12365 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012366 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012367 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012368 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012369 // Set this to null so that the reference
12370 // (local and remote) isnt kept in the mBroadcastHistory.
12371 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012372 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012373 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012374 }
12375 }
12376
Joe Onorato8a9b2202010-02-26 18:56:32 -080012377 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012378 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012379
Joe Onorato8a9b2202010-02-26 18:56:32 -080012380 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012381 + r);
12382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012383 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012384 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012385 mOrderedBroadcasts.remove(0);
12386 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012387 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012388 continue;
12389 }
12390 } while (r == null);
12391
12392 // Get the next receiver...
12393 int recIdx = r.nextReceiver++;
12394
12395 // Keep track of when this receiver started, and make sure there
12396 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012397 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012398 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012399 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012400 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012401 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012402 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012403 }
12404 if (! mPendingBroadcastTimeoutMessage) {
12405 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012406 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012407 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12408 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012409 }
12410
12411 Object nextReceiver = r.receivers.get(recIdx);
12412 if (nextReceiver instanceof BroadcastFilter) {
12413 // Simple case: this is a registered receiver who gets
12414 // a direct call.
12415 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012416 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012417 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012418 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012419 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012420 if (r.receiver == null || !r.ordered) {
12421 // The receiver has already finished, so schedule to
12422 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012423 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12424 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012425 r.state = BroadcastRecord.IDLE;
12426 scheduleBroadcastsLocked();
12427 }
12428 return;
12429 }
12430
12431 // Hard case: need to instantiate the receiver, possibly
12432 // starting its application process to host it.
12433
12434 ResolveInfo info =
12435 (ResolveInfo)nextReceiver;
12436
12437 boolean skip = false;
12438 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012439 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12440 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012441 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012442 if (!info.activityInfo.exported) {
12443 Slog.w(TAG, "Permission Denial: broadcasting "
12444 + r.intent.toString()
12445 + " from " + r.callerPackage + " (pid=" + r.callingPid
12446 + ", uid=" + r.callingUid + ")"
12447 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12448 + " due to receiver " + info.activityInfo.packageName
12449 + "/" + info.activityInfo.name);
12450 } else {
12451 Slog.w(TAG, "Permission Denial: broadcasting "
12452 + r.intent.toString()
12453 + " from " + r.callerPackage + " (pid=" + r.callingPid
12454 + ", uid=" + r.callingUid + ")"
12455 + " requires " + info.activityInfo.permission
12456 + " due to receiver " + info.activityInfo.packageName
12457 + "/" + info.activityInfo.name);
12458 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012459 skip = true;
12460 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012461 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012462 r.requiredPermission != null) {
12463 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012464 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012465 checkPermission(r.requiredPermission,
12466 info.activityInfo.applicationInfo.packageName);
12467 } catch (RemoteException e) {
12468 perm = PackageManager.PERMISSION_DENIED;
12469 }
12470 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012471 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012472 + r.intent + " to "
12473 + info.activityInfo.applicationInfo.packageName
12474 + " requires " + r.requiredPermission
12475 + " due to sender " + r.callerPackage
12476 + " (uid " + r.callingUid + ")");
12477 skip = true;
12478 }
12479 }
12480 if (r.curApp != null && r.curApp.crashing) {
12481 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012482 if (DEBUG_BROADCAST) Slog.v(TAG,
12483 "Skipping deliver ordered " + r + " to " + r.curApp
12484 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012485 skip = true;
12486 }
12487
12488 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012489 if (DEBUG_BROADCAST) Slog.v(TAG,
12490 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012491 r.receiver = null;
12492 r.curFilter = null;
12493 r.state = BroadcastRecord.IDLE;
12494 scheduleBroadcastsLocked();
12495 return;
12496 }
12497
12498 r.state = BroadcastRecord.APP_RECEIVE;
12499 String targetProcess = info.activityInfo.processName;
12500 r.curComponent = new ComponentName(
12501 info.activityInfo.applicationInfo.packageName,
12502 info.activityInfo.name);
12503 r.curReceiver = info.activityInfo;
12504
Dianne Hackborne7f97212011-02-24 14:40:20 -080012505 // Broadcast is being executed, its package can't be stopped.
12506 try {
12507 AppGlobals.getPackageManager().setPackageStoppedState(
12508 r.curComponent.getPackageName(), false);
12509 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012510 } catch (IllegalArgumentException e) {
12511 Slog.w(TAG, "Failed trying to unstop package "
12512 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012513 }
12514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012515 // Is this receiver's application already running?
12516 ProcessRecord app = getProcessRecordLocked(targetProcess,
12517 info.activityInfo.applicationInfo.uid);
12518 if (app != null && app.thread != null) {
12519 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012520 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012521 processCurBroadcastLocked(r, app);
12522 return;
12523 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012524 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012525 + r.curComponent, e);
12526 }
12527
12528 // If a dead object exception was thrown -- fall through to
12529 // restart the application.
12530 }
12531
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012532 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012533 if (DEBUG_BROADCAST) Slog.v(TAG,
12534 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012535 if ((r.curApp=startProcessLocked(targetProcess,
12536 info.activityInfo.applicationInfo, true,
12537 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012538 "broadcast", r.curComponent,
12539 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12540 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012541 // Ah, this recipient is unavailable. Finish it if necessary,
12542 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012543 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012544 + info.activityInfo.applicationInfo.packageName + "/"
12545 + info.activityInfo.applicationInfo.uid + " for broadcast "
12546 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012547 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012548 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12549 r.resultExtras, r.resultAbort, true);
12550 scheduleBroadcastsLocked();
12551 r.state = BroadcastRecord.IDLE;
12552 return;
12553 }
12554
12555 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012556 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012557 }
12558 }
12559
12560 // =========================================================
12561 // INSTRUMENTATION
12562 // =========================================================
12563
12564 public boolean startInstrumentation(ComponentName className,
12565 String profileFile, int flags, Bundle arguments,
12566 IInstrumentationWatcher watcher) {
12567 // Refuse possible leaked file descriptors
12568 if (arguments != null && arguments.hasFileDescriptors()) {
12569 throw new IllegalArgumentException("File descriptors passed in Bundle");
12570 }
12571
12572 synchronized(this) {
12573 InstrumentationInfo ii = null;
12574 ApplicationInfo ai = null;
12575 try {
12576 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012577 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012578 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012579 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012580 } catch (PackageManager.NameNotFoundException e) {
12581 }
12582 if (ii == null) {
12583 reportStartInstrumentationFailure(watcher, className,
12584 "Unable to find instrumentation info for: " + className);
12585 return false;
12586 }
12587 if (ai == null) {
12588 reportStartInstrumentationFailure(watcher, className,
12589 "Unable to find instrumentation target package: " + ii.targetPackage);
12590 return false;
12591 }
12592
12593 int match = mContext.getPackageManager().checkSignatures(
12594 ii.targetPackage, ii.packageName);
12595 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12596 String msg = "Permission Denial: starting instrumentation "
12597 + className + " from pid="
12598 + Binder.getCallingPid()
12599 + ", uid=" + Binder.getCallingPid()
12600 + " not allowed because package " + ii.packageName
12601 + " does not have a signature matching the target "
12602 + ii.targetPackage;
12603 reportStartInstrumentationFailure(watcher, className, msg);
12604 throw new SecurityException(msg);
12605 }
12606
12607 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012608 // Instrumentation can kill and relaunch even persistent processes
12609 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012610 ProcessRecord app = addAppLocked(ai);
12611 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012612 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012613 app.instrumentationProfileFile = profileFile;
12614 app.instrumentationArguments = arguments;
12615 app.instrumentationWatcher = watcher;
12616 app.instrumentationResultClass = className;
12617 Binder.restoreCallingIdentity(origId);
12618 }
12619
12620 return true;
12621 }
12622
12623 /**
12624 * Report errors that occur while attempting to start Instrumentation. Always writes the
12625 * error to the logs, but if somebody is watching, send the report there too. This enables
12626 * the "am" command to report errors with more information.
12627 *
12628 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12629 * @param cn The component name of the instrumentation.
12630 * @param report The error report.
12631 */
12632 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12633 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012634 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012635 try {
12636 if (watcher != null) {
12637 Bundle results = new Bundle();
12638 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12639 results.putString("Error", report);
12640 watcher.instrumentationStatus(cn, -1, results);
12641 }
12642 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012643 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012644 }
12645 }
12646
12647 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12648 if (app.instrumentationWatcher != null) {
12649 try {
12650 // NOTE: IInstrumentationWatcher *must* be oneway here
12651 app.instrumentationWatcher.instrumentationFinished(
12652 app.instrumentationClass,
12653 resultCode,
12654 results);
12655 } catch (RemoteException e) {
12656 }
12657 }
12658 app.instrumentationWatcher = null;
12659 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012660 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012661 app.instrumentationProfileFile = null;
12662 app.instrumentationArguments = null;
12663
Christopher Tate3dacd842011-08-19 14:56:15 -070012664 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012665 }
12666
12667 public void finishInstrumentation(IApplicationThread target,
12668 int resultCode, Bundle results) {
12669 // Refuse possible leaked file descriptors
12670 if (results != null && results.hasFileDescriptors()) {
12671 throw new IllegalArgumentException("File descriptors passed in Intent");
12672 }
12673
12674 synchronized(this) {
12675 ProcessRecord app = getRecordForAppLocked(target);
12676 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012677 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012678 return;
12679 }
12680 final long origId = Binder.clearCallingIdentity();
12681 finishInstrumentationLocked(app, resultCode, results);
12682 Binder.restoreCallingIdentity(origId);
12683 }
12684 }
12685
12686 // =========================================================
12687 // CONFIGURATION
12688 // =========================================================
12689
12690 public ConfigurationInfo getDeviceConfigurationInfo() {
12691 ConfigurationInfo config = new ConfigurationInfo();
12692 synchronized (this) {
12693 config.reqTouchScreen = mConfiguration.touchscreen;
12694 config.reqKeyboardType = mConfiguration.keyboard;
12695 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012696 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12697 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012698 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12699 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012700 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12701 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012702 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12703 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012704 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012705 }
12706 return config;
12707 }
12708
12709 public Configuration getConfiguration() {
12710 Configuration ci;
12711 synchronized(this) {
12712 ci = new Configuration(mConfiguration);
12713 }
12714 return ci;
12715 }
12716
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012717 public void updatePersistentConfiguration(Configuration values) {
12718 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12719 "updateConfiguration()");
12720 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12721 "updateConfiguration()");
12722 if (values == null) {
12723 throw new NullPointerException("Configuration must not be null");
12724 }
12725
12726 synchronized(this) {
12727 final long origId = Binder.clearCallingIdentity();
12728 updateConfigurationLocked(values, null, true);
12729 Binder.restoreCallingIdentity(origId);
12730 }
12731 }
12732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012733 public void updateConfiguration(Configuration values) {
12734 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12735 "updateConfiguration()");
12736
12737 synchronized(this) {
12738 if (values == null && mWindowManager != null) {
12739 // sentinel: fetch the current configuration from the window manager
12740 values = mWindowManager.computeNewConfiguration();
12741 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012742
12743 if (mWindowManager != null) {
12744 mProcessList.applyDisplaySize(mWindowManager);
12745 }
12746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012747 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012748 if (values != null) {
12749 Settings.System.clearConfiguration(values);
12750 }
12751 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012752 Binder.restoreCallingIdentity(origId);
12753 }
12754 }
12755
12756 /**
12757 * Do either or both things: (1) change the current configuration, and (2)
12758 * make sure the given activity is running with the (now) current
12759 * configuration. Returns true if the activity has been left running, or
12760 * false if <var>starting</var> is being destroyed to match the new
12761 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012762 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012763 */
12764 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012765 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012766 int changes = 0;
12767
12768 boolean kept = true;
12769
12770 if (values != null) {
12771 Configuration newConfig = new Configuration(mConfiguration);
12772 changes = newConfig.updateFrom(values);
12773 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012774 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012775 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012776 }
12777
Doug Zongker2bec3d42009-12-04 12:52:44 -080012778 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012779
12780 if (values.locale != null) {
12781 saveLocaleLocked(values.locale,
12782 !values.locale.equals(mConfiguration.locale),
12783 values.userSetLocale);
12784 }
12785
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012786 mConfigurationSeq++;
12787 if (mConfigurationSeq <= 0) {
12788 mConfigurationSeq = 1;
12789 }
12790 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012791 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012792 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012793
12794 AttributeCache ac = AttributeCache.instance();
12795 if (ac != null) {
12796 ac.updateConfiguration(mConfiguration);
12797 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012798
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012799 // Make sure all resources in our process are updated
12800 // right now, so that anyone who is going to retrieve
12801 // resource values after we return will be sure to get
12802 // the new ones. This is especially important during
12803 // boot, where the first config change needs to guarantee
12804 // all resources have that config before following boot
12805 // code is executed.
12806 mSystemThread.applyConfigurationToResources(newConfig);
12807
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012808 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012809 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12810 msg.obj = new Configuration(mConfiguration);
12811 mHandler.sendMessage(msg);
12812 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012813
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012814 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12815 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012816 try {
12817 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012818 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012819 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012820 app.thread.scheduleConfigurationChanged(mConfiguration);
12821 }
12822 } catch (Exception e) {
12823 }
12824 }
12825 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012826 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12827 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012828 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12829 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012830 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12831 broadcastIntentLocked(null, null,
12832 new Intent(Intent.ACTION_LOCALE_CHANGED),
12833 null, null, 0, null, null,
12834 null, false, false, MY_PID, Process.SYSTEM_UID);
12835 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012836 }
12837 }
12838
12839 if (changes != 0 && starting == null) {
12840 // If the configuration changed, and the caller is not already
12841 // in the process of starting an activity, then find the top
12842 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012843 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012844 }
12845
12846 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012847 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012848 // And we need to make sure at this point that all other activities
12849 // are made visible with the correct configuration.
12850 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012851 }
12852
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012853 if (values != null && mWindowManager != null) {
12854 mWindowManager.setNewConfiguration(mConfiguration);
12855 }
12856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012857 return kept;
12858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012859
12860 /**
12861 * Save the locale. You must be inside a synchronized (this) block.
12862 */
12863 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12864 if(isDiff) {
12865 SystemProperties.set("user.language", l.getLanguage());
12866 SystemProperties.set("user.region", l.getCountry());
12867 }
12868
12869 if(isPersist) {
12870 SystemProperties.set("persist.sys.language", l.getLanguage());
12871 SystemProperties.set("persist.sys.country", l.getCountry());
12872 SystemProperties.set("persist.sys.localevar", l.getVariant());
12873 }
12874 }
12875
12876 // =========================================================
12877 // LIFETIME MANAGEMENT
12878 // =========================================================
12879
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012880 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12881 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012882 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012883 // This adjustment has already been computed. If we are calling
12884 // from the top, we may have already computed our adjustment with
12885 // an earlier hidden adjustment that isn't really for us... if
12886 // so, use the new hidden adjustment.
12887 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012888 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012889 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012890 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012891 }
12892
12893 if (app.thread == null) {
12894 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012895 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012896 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012897 }
12898
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012899 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12900 app.adjSource = null;
12901 app.adjTarget = null;
12902 app.empty = false;
12903 app.hidden = false;
12904
12905 final int activitiesSize = app.activities.size();
12906
Dianne Hackborn7d608422011-08-07 16:24:18 -070012907 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012908 // The max adjustment doesn't allow this app to be anything
12909 // below foreground, so it is not worth doing work for it.
12910 app.adjType = "fixed";
12911 app.adjSeq = mAdjSeq;
12912 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012913 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012914 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012915 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012916 // System process can do UI, and when they do we want to have
12917 // them trim their memory after the user leaves the UI. To
12918 // facilitate this, here we need to determine whether or not it
12919 // is currently showing UI.
12920 app.systemNoUi = true;
12921 if (app == TOP_APP) {
12922 app.systemNoUi = false;
12923 } else if (activitiesSize > 0) {
12924 for (int j = 0; j < activitiesSize; j++) {
12925 final ActivityRecord r = app.activities.get(j);
12926 if (r.visible) {
12927 app.systemNoUi = false;
12928 break;
12929 }
12930 }
12931 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012932 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012933 }
12934
12935 final boolean hadForegroundActivities = app.foregroundActivities;
12936
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012937 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012938 app.keeping = false;
12939 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012940
The Android Open Source Project4df24232009-03-05 14:34:35 -080012941 // Determine the importance of the process, starting with most
12942 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012943 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012944 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012945 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012946 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012947 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012948 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012949 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012950 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012951 } else if (app.instrumentationClass != null) {
12952 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012953 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012954 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012955 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012956 } else if (app.curReceiver != null ||
12957 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12958 // An app that is currently receiving a broadcast also
12959 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012960 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012961 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012962 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012963 } else if (app.executingServices.size() > 0) {
12964 // An app that is currently executing a service callback also
12965 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012966 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012967 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012968 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012969 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012970 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012971 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012972 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012973 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012974 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012975 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012976 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012977 // A very not-needed process. If this is lower in the lru list,
12978 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012979 adj = hiddenAdj;
12980 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012981 app.hidden = true;
12982 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012983 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012984 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012985
12986 // Examine all activities if not already foreground.
12987 if (!app.foregroundActivities && activitiesSize > 0) {
12988 for (int j = 0; j < activitiesSize; j++) {
12989 final ActivityRecord r = app.activities.get(j);
12990 if (r.visible) {
12991 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012992 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12993 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012994 app.adjType = "visible";
12995 }
12996 schedGroup = Process.THREAD_GROUP_DEFAULT;
12997 app.hidden = false;
12998 app.foregroundActivities = true;
12999 break;
13000 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13001 || r.state == ActivityState.STOPPING) {
13002 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013003 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13004 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013005 app.adjType = "stopping";
13006 }
13007 app.foregroundActivities = true;
13008 }
13009 }
13010 }
13011
Dianne Hackborn7d608422011-08-07 16:24:18 -070013012 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013013 if (app.foregroundServices) {
13014 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013015 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013016 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013017 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013018 } else if (app.forcingToForeground != null) {
13019 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013020 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013021 app.adjType = "force-foreground";
13022 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013023 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013024 }
13025 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013026
Dianne Hackborn7d608422011-08-07 16:24:18 -070013027 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013028 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013029 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013030 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13031 app.adjType = "heavy";
13032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013033
Dianne Hackborn7d608422011-08-07 16:24:18 -070013034 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013035 // This process is hosting what we currently consider to be the
13036 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013037 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013038 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13039 app.adjType = "home";
13040 }
13041
Joe Onorato8a9b2202010-02-26 18:56:32 -080013042 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013043
The Android Open Source Project4df24232009-03-05 14:34:35 -080013044 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013045 // there are applications dependent on our services or providers, but
13046 // this gives us a baseline and makes sure we don't get into an
13047 // infinite recursion.
13048 app.adjSeq = mAdjSeq;
13049 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013050
Christopher Tate6fa95972009-06-05 18:43:55 -070013051 if (mBackupTarget != null && app == mBackupTarget.app) {
13052 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013053 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013054 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013055 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013056 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013057 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013058 }
13059 }
13060
Dianne Hackborn7d608422011-08-07 16:24:18 -070013061 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013062 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013063 final long now = SystemClock.uptimeMillis();
13064 // This process is more important if the top activity is
13065 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013066 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013067 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013068 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013069 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013070 if (app.hasShownUi) {
13071 // If this process has shown some UI, let it immediately
13072 // go to the LRU list because it may be pretty heavy with
13073 // UI stuff. We'll tag it with a label just to help
13074 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013075 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013076 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013077 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013078 } else {
13079 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13080 // This service has seen some activity within
13081 // recent memory, so we will keep its process ahead
13082 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013083 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
13084 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013085 app.adjType = "started-services";
13086 app.hidden = false;
13087 }
13088 }
13089 // If we have let the service slide into the background
13090 // state, still have some text describing what it is doing
13091 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013092 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013093 app.adjType = "started-bg-services";
13094 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013095 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013096 // Don't kill this process because it is doing work; it
13097 // has said it is doing work.
13098 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013099 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013100 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013101 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013102 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013103 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013104 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013105 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013106 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013107 // XXX should compute this based on the max of
13108 // all connected clients.
13109 ConnectionRecord cr = clist.get(i);
13110 if (cr.binding.client == app) {
13111 // Binding to ourself is not interesting.
13112 continue;
13113 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013114 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013115 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013116 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013117 int myHiddenAdj = hiddenAdj;
13118 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013119 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013120 myHiddenAdj = client.hiddenAdj;
13121 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013122 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013123 }
13124 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013125 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013126 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013127 String adjType = null;
13128 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13129 // Not doing bind OOM management, so treat
13130 // this guy more like a started service.
13131 if (app.hasShownUi) {
13132 // If this process has shown some UI, let it immediately
13133 // go to the LRU list because it may be pretty heavy with
13134 // UI stuff. We'll tag it with a label just to help
13135 // debug and understand what is going on.
13136 if (adj > clientAdj) {
13137 adjType = "bound-bg-ui-services";
13138 }
13139 clientAdj = adj;
13140 } else {
13141 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13142 // This service has not seen activity within
13143 // recent memory, so allow it to drop to the
13144 // LRU list if there is no other reason to keep
13145 // it around. We'll also tag it with a label just
13146 // to help debug and undertand what is going on.
13147 if (adj > clientAdj) {
13148 adjType = "bound-bg-services";
13149 }
13150 clientAdj = adj;
13151 }
13152 }
13153 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013154 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013155 // If this process has recently shown UI, and
13156 // the process that is binding to it is less
13157 // important than being visible, then we don't
13158 // care about the binding as much as we care
13159 // about letting this process get into the LRU
13160 // list to be killed and restarted if needed for
13161 // memory.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013162 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013163 adjType = "bound-bg-ui-services";
13164 } else {
13165 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13166 |Context.BIND_IMPORTANT)) != 0) {
13167 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013168 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013169 adj = clientAdj;
13170 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013171 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013172 }
13173 if (!client.hidden) {
13174 app.hidden = false;
13175 }
13176 if (client.keeping) {
13177 app.keeping = true;
13178 }
13179 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013180 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013181 }
13182 if (adjType != null) {
13183 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013184 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13185 .REASON_SERVICE_IN_USE;
13186 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013187 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013188 app.adjTarget = s.name;
13189 }
13190 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13191 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13192 schedGroup = Process.THREAD_GROUP_DEFAULT;
13193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013194 }
13195 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013196 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13197 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013198 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013199 (a.visible || a.state == ActivityState.RESUMED
13200 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013201 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013202 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13203 schedGroup = Process.THREAD_GROUP_DEFAULT;
13204 }
13205 app.hidden = false;
13206 app.adjType = "service";
13207 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13208 .REASON_SERVICE_IN_USE;
13209 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013210 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013211 app.adjTarget = s.name;
13212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013213 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013214 }
13215 }
13216 }
13217 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013218
Dianne Hackborn287952c2010-09-22 22:34:31 -070013219 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013220 // would like to avoid killing it unless it would prevent the current
13221 // application from running. By default we put the process in
13222 // with the rest of the background processes; as we scan through
13223 // its services we may bump it up from there.
13224 if (adj > hiddenAdj) {
13225 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013226 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013227 app.adjType = "bg-services";
13228 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013229 }
13230
Dianne Hackborn7d608422011-08-07 16:24:18 -070013231 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013232 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013233 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013234 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013235 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013236 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013237 if (cpr.clients.size() != 0) {
13238 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013239 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013240 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013241 if (client == app) {
13242 // Being our own client is not interesting.
13243 continue;
13244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013245 int myHiddenAdj = hiddenAdj;
13246 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013247 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013248 myHiddenAdj = client.hiddenAdj;
13249 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013250 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013251 }
13252 }
13253 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013254 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013255 if (adj > clientAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013256 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013257 app.adjType = "bg-ui-provider";
13258 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013259 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13260 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013261 app.adjType = "provider";
13262 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013263 if (!client.hidden) {
13264 app.hidden = false;
13265 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013266 if (client.keeping) {
13267 app.keeping = true;
13268 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013269 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13270 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013271 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013272 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013273 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013274 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013275 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13276 schedGroup = Process.THREAD_GROUP_DEFAULT;
13277 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013278 }
13279 }
13280 // If the provider has external (non-framework) process
13281 // dependencies, ensure that its adjustment is at least
13282 // FOREGROUND_APP_ADJ.
13283 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013284 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13285 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013286 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013287 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013288 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013289 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013290 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013291 }
13292 }
13293 }
13294 }
13295
13296 app.curRawAdj = adj;
13297
Joe Onorato8a9b2202010-02-26 18:56:32 -080013298 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013299 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13300 if (adj > app.maxAdj) {
13301 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013302 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013303 schedGroup = Process.THREAD_GROUP_DEFAULT;
13304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013305 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013306 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013307 app.keeping = true;
13308 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013309
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013310 if (app.hasAboveClient) {
13311 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13312 // then we need to drop its adjustment to be lower than the service's
13313 // in order to honor the request. We want to drop it by one adjustment
13314 // level... but there is special meaning applied to various levels so
13315 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013316 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013317 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013318 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13319 adj = ProcessList.VISIBLE_APP_ADJ;
13320 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13321 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13322 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13323 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13324 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013325 adj++;
13326 }
13327 }
13328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013329 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013330 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013331
13332 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013333 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13334 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013335 }
13336
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013337 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013338 }
13339
13340 /**
13341 * Ask a given process to GC right now.
13342 */
13343 final void performAppGcLocked(ProcessRecord app) {
13344 try {
13345 app.lastRequestedGc = SystemClock.uptimeMillis();
13346 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013347 if (app.reportLowMemory) {
13348 app.reportLowMemory = false;
13349 app.thread.scheduleLowMemory();
13350 } else {
13351 app.thread.processInBackground();
13352 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013353 }
13354 } catch (Exception e) {
13355 // whatever.
13356 }
13357 }
13358
13359 /**
13360 * Returns true if things are idle enough to perform GCs.
13361 */
Josh Bartel7f208742010-02-25 11:01:44 -060013362 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013363 return mParallelBroadcasts.size() == 0
13364 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013365 && (mSleeping || (mMainStack.mResumedActivity != null &&
13366 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013367 }
13368
13369 /**
13370 * Perform GCs on all processes that are waiting for it, but only
13371 * if things are idle.
13372 */
13373 final void performAppGcsLocked() {
13374 final int N = mProcessesToGc.size();
13375 if (N <= 0) {
13376 return;
13377 }
Josh Bartel7f208742010-02-25 11:01:44 -060013378 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013379 while (mProcessesToGc.size() > 0) {
13380 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013381 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013382 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13383 <= SystemClock.uptimeMillis()) {
13384 // To avoid spamming the system, we will GC processes one
13385 // at a time, waiting a few seconds between each.
13386 performAppGcLocked(proc);
13387 scheduleAppGcsLocked();
13388 return;
13389 } else {
13390 // It hasn't been long enough since we last GCed this
13391 // process... put it in the list to wait for its time.
13392 addProcessToGcListLocked(proc);
13393 break;
13394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013395 }
13396 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013397
13398 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013399 }
13400 }
13401
13402 /**
13403 * If all looks good, perform GCs on all processes waiting for them.
13404 */
13405 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013406 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013407 performAppGcsLocked();
13408 return;
13409 }
13410 // Still not idle, wait some more.
13411 scheduleAppGcsLocked();
13412 }
13413
13414 /**
13415 * Schedule the execution of all pending app GCs.
13416 */
13417 final void scheduleAppGcsLocked() {
13418 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013419
13420 if (mProcessesToGc.size() > 0) {
13421 // Schedule a GC for the time to the next process.
13422 ProcessRecord proc = mProcessesToGc.get(0);
13423 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13424
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013425 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013426 long now = SystemClock.uptimeMillis();
13427 if (when < (now+GC_TIMEOUT)) {
13428 when = now + GC_TIMEOUT;
13429 }
13430 mHandler.sendMessageAtTime(msg, when);
13431 }
13432 }
13433
13434 /**
13435 * Add a process to the array of processes waiting to be GCed. Keeps the
13436 * list in sorted order by the last GC time. The process can't already be
13437 * on the list.
13438 */
13439 final void addProcessToGcListLocked(ProcessRecord proc) {
13440 boolean added = false;
13441 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13442 if (mProcessesToGc.get(i).lastRequestedGc <
13443 proc.lastRequestedGc) {
13444 added = true;
13445 mProcessesToGc.add(i+1, proc);
13446 break;
13447 }
13448 }
13449 if (!added) {
13450 mProcessesToGc.add(0, proc);
13451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013452 }
13453
13454 /**
13455 * Set up to ask a process to GC itself. This will either do it
13456 * immediately, or put it on the list of processes to gc the next
13457 * time things are idle.
13458 */
13459 final void scheduleAppGcLocked(ProcessRecord app) {
13460 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013461 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013462 return;
13463 }
13464 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013465 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013466 scheduleAppGcsLocked();
13467 }
13468 }
13469
Dianne Hackborn287952c2010-09-22 22:34:31 -070013470 final void checkExcessivePowerUsageLocked(boolean doKills) {
13471 updateCpuStatsNow();
13472
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013473 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013474 boolean doWakeKills = doKills;
13475 boolean doCpuKills = doKills;
13476 if (mLastPowerCheckRealtime == 0) {
13477 doWakeKills = false;
13478 }
13479 if (mLastPowerCheckUptime == 0) {
13480 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013481 }
13482 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013483 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013484 }
13485 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013486 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13487 final long curUptime = SystemClock.uptimeMillis();
13488 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13489 mLastPowerCheckRealtime = curRealtime;
13490 mLastPowerCheckUptime = curUptime;
13491 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13492 doWakeKills = false;
13493 }
13494 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13495 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013496 }
13497 int i = mLruProcesses.size();
13498 while (i > 0) {
13499 i--;
13500 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013501 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013502 long wtime;
13503 synchronized (stats) {
13504 wtime = stats.getProcessWakeTime(app.info.uid,
13505 app.pid, curRealtime);
13506 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013507 long wtimeUsed = wtime - app.lastWakeTime;
13508 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13509 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013510 StringBuilder sb = new StringBuilder(128);
13511 sb.append("Wake for ");
13512 app.toShortString(sb);
13513 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013514 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013515 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013516 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013517 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013518 sb.append((wtimeUsed*100)/realtimeSince);
13519 sb.append("%)");
13520 Slog.i(TAG, sb.toString());
13521 sb.setLength(0);
13522 sb.append("CPU for ");
13523 app.toShortString(sb);
13524 sb.append(": over ");
13525 TimeUtils.formatDuration(uptimeSince, sb);
13526 sb.append(" used ");
13527 TimeUtils.formatDuration(cputimeUsed, sb);
13528 sb.append(" (");
13529 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013530 sb.append("%)");
13531 Slog.i(TAG, sb.toString());
13532 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013533 // If a process has held a wake lock for more
13534 // than 50% of the time during this period,
13535 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013536 if (doWakeKills && realtimeSince > 0
13537 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13538 synchronized (stats) {
13539 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13540 realtimeSince, wtimeUsed);
13541 }
13542 Slog.w(TAG, "Excessive wake lock in " + app.processName
13543 + " (pid " + app.pid + "): held " + wtimeUsed
13544 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013545 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13546 app.processName, app.setAdj, "excessive wake lock");
13547 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013548 } else if (doCpuKills && uptimeSince > 0
13549 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13550 synchronized (stats) {
13551 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13552 uptimeSince, cputimeUsed);
13553 }
13554 Slog.w(TAG, "Excessive CPU in " + app.processName
13555 + " (pid " + app.pid + "): used " + cputimeUsed
13556 + " during " + uptimeSince);
13557 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13558 app.processName, app.setAdj, "excessive cpu");
13559 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013560 } else {
13561 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013562 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013563 }
13564 }
13565 }
13566 }
13567
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013568 private final boolean updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013569 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013570 app.hiddenAdj = hiddenAdj;
13571
13572 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013573 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013574 }
13575
Dianne Hackborn287952c2010-09-22 22:34:31 -070013576 final boolean wasKeeping = app.keeping;
13577
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013578 boolean success = true;
13579
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013580 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013581
Jeff Brown10e89712011-07-08 18:52:57 -070013582 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070013583 if (false) {
13584 // Removing for now. Forcing GCs is not so useful anymore
13585 // with Dalvik, and the new memory level hint facility is
13586 // better for what we need to do these days.
13587 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13588 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13589 // If this app is transitioning from foreground to
13590 // non-foreground, have it do a gc.
13591 scheduleAppGcLocked(app);
13592 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13593 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13594 // Likewise do a gc when an app is moving in to the
13595 // background (such as a service stopping).
13596 scheduleAppGcLocked(app);
13597 }
Jeff Brown10e89712011-07-08 18:52:57 -070013598 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013599
Jeff Brown10e89712011-07-08 18:52:57 -070013600 if (wasKeeping && !app.keeping) {
13601 // This app is no longer something we want to keep. Note
13602 // its current wake lock time to later know to kill it if
13603 // it is not behaving well.
13604 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13605 synchronized (stats) {
13606 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13607 app.pid, SystemClock.elapsedRealtime());
13608 }
13609 app.lastCpuTime = app.curCpuTime;
13610 }
13611
13612 app.setRawAdj = app.curRawAdj;
13613 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013614 if (app.curAdj != app.setAdj) {
13615 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013616 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13617 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013618 " oom adj to " + app.curAdj + " because " + app.adjType);
13619 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013620 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013621 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013622 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013623 }
13624 }
13625 if (app.setSchedGroup != app.curSchedGroup) {
13626 app.setSchedGroup = app.curSchedGroup;
13627 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13628 "Setting process group of " + app.processName
13629 + " to " + app.curSchedGroup);
13630 if (app.waitingToKill != null &&
13631 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13632 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13633 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13634 app.processName, app.setAdj, app.waitingToKill);
13635 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013636 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013637 } else {
13638 if (true) {
13639 long oldId = Binder.clearCallingIdentity();
13640 try {
13641 Process.setProcessGroup(app.pid, app.curSchedGroup);
13642 } catch (Exception e) {
13643 Slog.w(TAG, "Failed setting process group of " + app.pid
13644 + " to " + app.curSchedGroup);
13645 e.printStackTrace();
13646 } finally {
13647 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013648 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013649 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013650 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013651 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013652 app.thread.setSchedulingGroup(app.curSchedGroup);
13653 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013654 }
13655 }
13656 }
13657 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013658 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013659 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013660 }
13661
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013662 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013663 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013664 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013665 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013666 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013667 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013668 }
13669 }
13670 return resumedActivity;
13671 }
13672
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013673 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013674 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013675 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13676 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013677 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13678 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013679
13680 mAdjSeq++;
13681
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013682 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013683 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13684 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013685 if (nowHidden != wasHidden) {
13686 // Changed to/from hidden state, so apps after it in the LRU
13687 // list may also be changed.
13688 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013689 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013690 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013691 }
13692
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013693 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013694 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013695 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13696
13697 if (false) {
13698 RuntimeException e = new RuntimeException();
13699 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013700 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013701 }
13702
13703 mAdjSeq++;
13704
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013705 // Let's determine how many processes we have running vs.
13706 // how many slots we have for background processes; we may want
13707 // to put multiple processes in a slot of there are enough of
13708 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013709 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013710 int factor = (mLruProcesses.size()-4)/numSlots;
13711 if (factor < 1) factor = 1;
13712 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013713 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013714
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013715 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013716 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013717 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013718 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013719 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013720 while (i > 0) {
13721 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013722 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013723 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013724 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013725 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013726 && app.curAdj == curHiddenAdj) {
13727 step++;
13728 if (step >= factor) {
13729 step = 0;
13730 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013731 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013732 }
13733 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013734 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013735 numHidden++;
13736 if (numHidden > mProcessLimit) {
13737 Slog.i(TAG, "No longer want " + app.processName
13738 + " (pid " + app.pid + "): hidden #" + numHidden);
13739 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13740 app.processName, app.setAdj, "too many background");
13741 app.killedBackground = true;
13742 Process.killProcessQuiet(app.pid);
13743 } else {
13744 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013745 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013746 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013747 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013748 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013749 }
13750 }
13751
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013752 // Now determine the memory trimming level of background processes.
13753 // Unfortunately we need to start at the back of the list to do this
13754 // properly. We only do this if the number of background apps we
13755 // are managing to keep around is less than half the maximum we desire;
13756 // if we are keeping a good number around, we'll let them use whatever
13757 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013758 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013759 final int N = mLruProcesses.size();
13760 factor = numBg/3;
13761 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013762 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013763 for (i=0; i<N; i++) {
13764 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013765 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013766 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13767 try {
13768 app.thread.scheduleTrimMemory(curLevel);
13769 } catch (RemoteException e) {
13770 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013771 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013772 // For these apps we will also finish their activities
13773 // to help them free memory.
13774 mMainStack.destroyActivitiesLocked(app, false);
13775 }
13776 }
13777 app.trimMemoryLevel = curLevel;
13778 step++;
13779 if (step >= factor) {
13780 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013781 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13782 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013783 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013784 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13785 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013786 break;
13787 }
13788 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013789 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013790 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013791 && app.thread != null) {
13792 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013793 app.thread.scheduleTrimMemory(
13794 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013795 } catch (RemoteException e) {
13796 }
13797 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013798 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013799 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013800 && app.pendingUiClean) {
13801 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13802 && app.thread != null) {
13803 try {
13804 app.thread.scheduleTrimMemory(
13805 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13806 } catch (RemoteException e) {
13807 }
13808 }
13809 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13810 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013811 } else {
13812 app.trimMemoryLevel = 0;
13813 }
13814 }
13815 } else {
13816 final int N = mLruProcesses.size();
13817 for (i=0; i<N; i++) {
13818 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013819 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013820 && app.pendingUiClean) {
13821 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13822 && app.thread != null) {
13823 try {
13824 app.thread.scheduleTrimMemory(
13825 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13826 } catch (RemoteException e) {
13827 }
13828 }
13829 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13830 app.pendingUiClean = false;
13831 } else {
13832 app.trimMemoryLevel = 0;
13833 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013834 }
13835 }
13836
13837 if (mAlwaysFinishActivities) {
13838 mMainStack.destroyActivitiesLocked(null, false);
13839 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013840 }
13841
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013842 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013843 synchronized (this) {
13844 int i;
13845
13846 // First remove any unused application processes whose package
13847 // has been removed.
13848 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13849 final ProcessRecord app = mRemovedProcesses.get(i);
13850 if (app.activities.size() == 0
13851 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013852 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013853 TAG, "Exiting empty application process "
13854 + app.processName + " ("
13855 + (app.thread != null ? app.thread.asBinder() : null)
13856 + ")\n");
13857 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013858 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13859 app.processName, app.setAdj, "empty");
13860 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013861 } else {
13862 try {
13863 app.thread.scheduleExit();
13864 } catch (Exception e) {
13865 // Ignore exceptions.
13866 }
13867 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013868 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013869 mRemovedProcesses.remove(i);
13870
13871 if (app.persistent) {
13872 if (app.persistent) {
13873 addAppLocked(app.info);
13874 }
13875 }
13876 }
13877 }
13878
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013879 // Now update the oom adj for all processes.
13880 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013881 }
13882 }
13883
13884 /** This method sends the specified signal to each of the persistent apps */
13885 public void signalPersistentProcesses(int sig) throws RemoteException {
13886 if (sig != Process.SIGNAL_USR1) {
13887 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13888 }
13889
13890 synchronized (this) {
13891 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13892 != PackageManager.PERMISSION_GRANTED) {
13893 throw new SecurityException("Requires permission "
13894 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13895 }
13896
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013897 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13898 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013899 if (r.thread != null && r.persistent) {
13900 Process.sendSignal(r.pid, sig);
13901 }
13902 }
13903 }
13904 }
13905
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013906 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13907 if (proc == null || proc == mProfileProc) {
13908 proc = mProfileProc;
13909 path = mProfileFile;
13910 profileType = mProfileType;
13911 clearProfilerLocked();
13912 }
13913 if (proc == null) {
13914 return;
13915 }
13916 try {
13917 proc.thread.profilerControl(false, path, null, profileType);
13918 } catch (RemoteException e) {
13919 throw new IllegalStateException("Process disappeared");
13920 }
13921 }
13922
13923 private void clearProfilerLocked() {
13924 if (mProfileFd != null) {
13925 try {
13926 mProfileFd.close();
13927 } catch (IOException e) {
13928 }
13929 }
13930 mProfileApp = null;
13931 mProfileProc = null;
13932 mProfileFile = null;
13933 mProfileType = 0;
13934 mAutoStopProfiler = false;
13935 }
13936
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013937 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013938 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013939
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013940 try {
13941 synchronized (this) {
13942 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13943 // its own permission.
13944 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13945 != PackageManager.PERMISSION_GRANTED) {
13946 throw new SecurityException("Requires permission "
13947 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013948 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013949
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013950 if (start && fd == null) {
13951 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013952 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013953
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013954 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013955 if (process != null) {
13956 try {
13957 int pid = Integer.parseInt(process);
13958 synchronized (mPidsSelfLocked) {
13959 proc = mPidsSelfLocked.get(pid);
13960 }
13961 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013962 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013963
13964 if (proc == null) {
13965 HashMap<String, SparseArray<ProcessRecord>> all
13966 = mProcessNames.getMap();
13967 SparseArray<ProcessRecord> procs = all.get(process);
13968 if (procs != null && procs.size() > 0) {
13969 proc = procs.valueAt(0);
13970 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013971 }
13972 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013973
13974 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013975 throw new IllegalArgumentException("Unknown process: " + process);
13976 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013977
13978 if (start) {
13979 stopProfilerLocked(null, null, 0);
13980 setProfileApp(proc.info, proc.processName, path, fd, false);
13981 mProfileProc = proc;
13982 mProfileType = profileType;
13983 try {
13984 fd = fd.dup();
13985 } catch (IOException e) {
13986 fd = null;
13987 }
13988 proc.thread.profilerControl(start, path, fd, profileType);
13989 fd = null;
13990 mProfileFd = null;
13991 } else {
13992 stopProfilerLocked(proc, path, profileType);
13993 if (fd != null) {
13994 try {
13995 fd.close();
13996 } catch (IOException e) {
13997 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013998 }
13999 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014000
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014001 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014002 }
14003 } catch (RemoteException e) {
14004 throw new IllegalStateException("Process disappeared");
14005 } finally {
14006 if (fd != null) {
14007 try {
14008 fd.close();
14009 } catch (IOException e) {
14010 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014011 }
14012 }
14013 }
Andy McFadden824c5102010-07-09 16:26:57 -070014014
14015 public boolean dumpHeap(String process, boolean managed,
14016 String path, ParcelFileDescriptor fd) throws RemoteException {
14017
14018 try {
14019 synchronized (this) {
14020 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14021 // its own permission (same as profileControl).
14022 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14023 != PackageManager.PERMISSION_GRANTED) {
14024 throw new SecurityException("Requires permission "
14025 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14026 }
14027
14028 if (fd == null) {
14029 throw new IllegalArgumentException("null fd");
14030 }
14031
14032 ProcessRecord proc = null;
14033 try {
14034 int pid = Integer.parseInt(process);
14035 synchronized (mPidsSelfLocked) {
14036 proc = mPidsSelfLocked.get(pid);
14037 }
14038 } catch (NumberFormatException e) {
14039 }
14040
14041 if (proc == null) {
14042 HashMap<String, SparseArray<ProcessRecord>> all
14043 = mProcessNames.getMap();
14044 SparseArray<ProcessRecord> procs = all.get(process);
14045 if (procs != null && procs.size() > 0) {
14046 proc = procs.valueAt(0);
14047 }
14048 }
14049
14050 if (proc == null || proc.thread == null) {
14051 throw new IllegalArgumentException("Unknown process: " + process);
14052 }
14053
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014054 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14055 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014056 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14057 throw new SecurityException("Process not debuggable: " + proc);
14058 }
14059 }
14060
14061 proc.thread.dumpHeap(managed, path, fd);
14062 fd = null;
14063 return true;
14064 }
14065 } catch (RemoteException e) {
14066 throw new IllegalStateException("Process disappeared");
14067 } finally {
14068 if (fd != null) {
14069 try {
14070 fd.close();
14071 } catch (IOException e) {
14072 }
14073 }
14074 }
14075 }
14076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014077 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14078 public void monitor() {
14079 synchronized (this) { }
14080 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014081
14082 public void onCoreSettingsChange(Bundle settings) {
14083 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14084 ProcessRecord processRecord = mLruProcesses.get(i);
14085 try {
14086 if (processRecord.thread != null) {
14087 processRecord.thread.setCoreSettings(settings);
14088 }
14089 } catch (RemoteException re) {
14090 /* ignore */
14091 }
14092 }
14093 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014094
14095 // Multi-user methods
14096
14097 public boolean switchUser(int userid) {
14098 // TODO
14099 return true;
14100 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014101}