blob: 4067f6e40a5daedb07bda5a5c68cc4272d33a4ca [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;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700123import java.io.BufferedReader;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700124import java.io.DataInputStream;
125import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126import java.io.File;
127import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700130import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200131import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800132import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133import java.io.PrintWriter;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700134import java.io.StringWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135import java.lang.IllegalStateException;
136import java.lang.ref.WeakReference;
137import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700138import java.util.Collections;
139import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140import java.util.HashMap;
141import java.util.HashSet;
142import java.util.Iterator;
143import java.util.List;
144import java.util.Locale;
145import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700146import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700147import java.util.concurrent.atomic.AtomicBoolean;
148import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700150public final class ActivityManagerService extends ActivityManagerNative
151 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final String TAG = "ActivityManager";
153 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400154 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 static final boolean DEBUG_SWITCH = localLOGV || false;
156 static final boolean DEBUG_TASKS = localLOGV || false;
157 static final boolean DEBUG_PAUSE = localLOGV || false;
158 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
159 static final boolean DEBUG_TRANSITION = localLOGV || false;
160 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700161 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700163 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 static final boolean DEBUG_VISBILITY = localLOGV || false;
165 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700166 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800167 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700169 static final boolean DEBUG_RESULTS = localLOGV || false;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -0700170 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700171 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700172 static final boolean DEBUG_POWER = localLOGV || false;
173 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 static final boolean VALIDATE_TOKENS = false;
175 static final boolean SHOW_ACTIVITY_START_TIME = true;
176
177 // Control over CPU and battery monitoring.
178 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
179 static final boolean MONITOR_CPU_USAGE = true;
180 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
181 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
182 static final boolean MONITOR_THREAD_CPU_USAGE = false;
183
Dianne Hackborn1655be42009-05-08 14:29:01 -0700184 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700185 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700186
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800187 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 // Maximum number of recent tasks that we can remember.
190 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700191
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700192 // Amount of time after a call to stopAppSwitches() during which we will
193 // prevent further untrusted switches from happening.
194 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195
196 // How long we wait for a launched process to attach to the activity manager
197 // before we decide it's never going to come up for real.
198 static final int PROC_START_TIMEOUT = 10*1000;
199
Jeff Brown3f9dd282011-07-08 20:02:19 -0700200 // How long we wait for a launched process to attach to the activity manager
201 // before we decide it's never going to come up for real, when the process was
202 // started with a wrapper for instrumentation (such as Valgrind) because it
203 // could take much longer than usual.
204 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 // How long to wait after going idle before forcing apps to GC.
207 static final int GC_TIMEOUT = 5*1000;
208
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700209 // The minimum amount of time between successive GC requests for a process.
210 static final int GC_MIN_INTERVAL = 60*1000;
211
Dianne Hackborn287952c2010-09-22 22:34:31 -0700212 // The rate at which we check for apps using excessive power -- 15 mins.
213 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
214
215 // The minimum sample duration we will allow before deciding we have
216 // enough data on wake locks to start killing things.
217 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
218
219 // The minimum sample duration we will allow before deciding we have
220 // enough data on CPU usage to start killing things.
221 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 // How long we allow a receiver to run before giving up on it.
224 static final int BROADCAST_TIMEOUT = 10*1000;
225
226 // How long we wait for a service to finish executing.
227 static final int SERVICE_TIMEOUT = 20*1000;
228
229 // How long a service needs to be running until restarting its process
230 // is no longer considered to be a relaunch of the service.
231 static final int SERVICE_RESTART_DURATION = 5*1000;
232
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700233 // How long a service needs to be running until it will start back at
234 // SERVICE_RESTART_DURATION after being killed.
235 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
236
237 // Multiplying factor to increase restart duration time by, for each time
238 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
239 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
240
241 // The minimum amount of time between restarting services that we allow.
242 // That is, when multiple services are restarting, we won't allow each
243 // to restart less than this amount of time from the last one.
244 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 // Maximum amount of time for there to be no activity on a service before
247 // we consider it non-essential and allow its process to go on the
248 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700249 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250
251 // How long we wait until we timeout on key dispatching.
252 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 // How long we wait until we timeout on key dispatching during instrumentation.
255 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
256
Dan Egnor42471dd2010-01-07 17:25:22 -0800257 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258
259 static final String[] EMPTY_STRING_ARRAY = new String[0];
260
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700261 public ActivityStack mMainStack;
262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700264 * Description of a request to start a new activity, which has been held
265 * due to app switches being disabled.
266 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700267 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700268 ActivityRecord r;
269 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700270 Uri[] grantedUriPermissions;
271 int grantedMode;
272 boolean onlyIfNeeded;
273 }
274
275 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
276 = new ArrayList<PendingActivityLaunch>();
277
278 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 * List of all active broadcasts that are to be executed immediately
280 * (without waiting for another broadcast to finish). Currently this only
281 * contains broadcasts to registered receivers, to avoid spinning up
282 * a bunch of processes to execute IntentReceiver components.
283 */
284 final ArrayList<BroadcastRecord> mParallelBroadcasts
285 = new ArrayList<BroadcastRecord>();
286
287 /**
288 * List of all active broadcasts that are to be executed one at a time.
289 * The object at the top of the list is the currently activity broadcasts;
290 * those after it are waiting for the top to finish..
291 */
292 final ArrayList<BroadcastRecord> mOrderedBroadcasts
293 = new ArrayList<BroadcastRecord>();
294
295 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800296 * Historical data of past broadcasts, for debugging.
297 */
Dianne Hackborn28695e02011-11-02 21:59:51 -0700298 static final int MAX_BROADCAST_HISTORY = 25;
Dianne Hackborn12527f92009-11-11 17:39:50 -0800299 final BroadcastRecord[] mBroadcastHistory
300 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
301
302 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 * Set when we current have a BROADCAST_INTENT_MSG in flight.
304 */
305 boolean mBroadcastsScheduled = false;
306
307 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 * Activity we have told the window manager to have key focus.
309 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700310 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700311 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 * List of intents that were used to start the most recent tasks.
313 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700314 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315
316 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700317 * Process management.
318 */
319 final ProcessList mProcessList = new ProcessList();
320
321 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 * All of the applications we currently have running organized by name.
323 * The keys are strings of the application package name (as
324 * returned by the package manager), and the keys are ApplicationRecord
325 * objects.
326 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700327 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328
329 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700330 * The currently running heavy-weight process, if any.
331 */
332 ProcessRecord mHeavyWeightProcess = null;
333
334 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 * The last time that various processes have crashed.
336 */
337 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
338
339 /**
340 * Set of applications that we consider to be bad, and will reject
341 * incoming broadcasts from (which the user has no control over).
342 * Processes are added to this set when they have crashed twice within
343 * a minimum amount of time; they are removed from it when they are
344 * later restarted (hopefully due to some user action). The value is the
345 * time it was added to the list.
346 */
347 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
348
349 /**
350 * All of the processes we currently have running organized by pid.
351 * The keys are the pid running the application.
352 *
353 * <p>NOTE: This object is protected by its own lock, NOT the global
354 * activity manager lock!
355 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700356 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357
358 /**
359 * All of the processes that have been forced to be foreground. The key
360 * is the pid of the caller who requested it (we hold a death
361 * link on it).
362 */
363 abstract class ForegroundToken implements IBinder.DeathRecipient {
364 int pid;
365 IBinder token;
366 }
367 final SparseArray<ForegroundToken> mForegroundProcesses
368 = new SparseArray<ForegroundToken>();
369
370 /**
371 * List of records for processes that someone had tried to start before the
372 * system was ready. We don't start them at that point, but ensure they
373 * are started by the time booting is complete.
374 */
375 final ArrayList<ProcessRecord> mProcessesOnHold
376 = new ArrayList<ProcessRecord>();
377
378 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 * List of persistent applications that are in the process
380 * of being started.
381 */
382 final ArrayList<ProcessRecord> mPersistentStartingProcesses
383 = new ArrayList<ProcessRecord>();
384
385 /**
386 * Processes that are being forcibly torn down.
387 */
388 final ArrayList<ProcessRecord> mRemovedProcesses
389 = new ArrayList<ProcessRecord>();
390
391 /**
392 * List of running applications, sorted by recent usage.
393 * The first entry in the list is the least recently used.
394 * It contains ApplicationRecord objects. This list does NOT include
395 * any persistent application records (since we never want to exit them).
396 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800397 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 = new ArrayList<ProcessRecord>();
399
400 /**
401 * List of processes that should gc as soon as things are idle.
402 */
403 final ArrayList<ProcessRecord> mProcessesToGc
404 = new ArrayList<ProcessRecord>();
405
406 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800407 * This is the process holding what we currently consider to be
408 * the "home" activity.
409 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700410 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800411
412 /**
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700413 * This is the process holding the activity the user last visited that
414 * is in a different process from the one they are currently in.
415 */
416 ProcessRecord mPreviousProcess;
Dianne Hackborn50685602011-12-01 12:23:37 -0800417
418 /**
419 * The time at which the previous process was last visible.
420 */
421 long mPreviousProcessVisibleTime;
422
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700423 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400424 * Packages that the user has asked to have run in screen size
425 * compatibility mode instead of filling the screen.
426 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700427 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400428
429 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 * Set of PendingResultRecord objects that are currently active.
431 */
432 final HashSet mPendingResultRecords = new HashSet();
433
434 /**
435 * Set of IntentSenderRecord objects that are currently active.
436 */
437 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
438 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
439
440 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800441 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700442 * already logged DropBox entries for. Guarded by itself. If
443 * something (rogue user app) forces this over
444 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
445 */
446 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
447 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
448
449 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700450 * Strict Mode background batched logging state.
451 *
452 * The string buffer is guarded by itself, and its lock is also
453 * used to determine if another batched write is already
454 * in-flight.
455 */
456 private final StringBuilder mStrictModeBuffer = new StringBuilder();
457
458 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700459 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
460 */
461 private boolean mPendingBroadcastTimeoutMessage;
462
463 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 * Intent broadcast that we have tried to start, but are
465 * waiting for its application's process to be created. We only
466 * need one (instead of a list) because we always process broadcasts
467 * one at a time, so no others can be started while waiting for this
468 * one.
469 */
470 BroadcastRecord mPendingBroadcast = null;
471
472 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700473 * The receiver index that is pending, to restart the broadcast if needed.
474 */
475 int mPendingBroadcastRecvIndex;
476
477 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 * Keeps track of all IIntentReceivers that have been registered for
479 * broadcasts. Hash keys are the receiver IBinder, hash value is
480 * a ReceiverList.
481 */
482 final HashMap mRegisteredReceivers = new HashMap();
483
484 /**
485 * Resolver for broadcast intents to registered receivers.
486 * Holds BroadcastFilter (subclass of IntentFilter).
487 */
488 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
489 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
490 @Override
491 protected boolean allowFilterResult(
492 BroadcastFilter filter, List<BroadcastFilter> dest) {
493 IBinder target = filter.receiverList.receiver.asBinder();
494 for (int i=dest.size()-1; i>=0; i--) {
495 if (dest.get(i).receiverList.receiver.asBinder() == target) {
496 return false;
497 }
498 }
499 return true;
500 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700501
502 @Override
503 protected String packageForFilter(BroadcastFilter filter) {
504 return filter.packageName;
505 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 };
507
508 /**
509 * State of all active sticky broadcasts. Keys are the action of the
510 * sticky Intent, values are an ArrayList of all broadcasted intents with
511 * that action (which should usually be one).
512 */
513 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
514 new HashMap<String, ArrayList<Intent>>();
515
516 /**
517 * All currently running services.
518 */
519 final HashMap<ComponentName, ServiceRecord> mServices =
520 new HashMap<ComponentName, ServiceRecord>();
521
522 /**
523 * All currently running services indexed by the Intent used to start them.
524 */
525 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
526 new HashMap<Intent.FilterComparison, ServiceRecord>();
527
528 /**
529 * All currently bound service connections. Keys are the IBinder of
530 * the client's IServiceConnection.
531 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700532 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
533 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534
535 /**
536 * List of services that we have been asked to start,
537 * but haven't yet been able to. It is used to hold start requests
538 * while waiting for their corresponding application thread to get
539 * going.
540 */
541 final ArrayList<ServiceRecord> mPendingServices
542 = new ArrayList<ServiceRecord>();
543
544 /**
545 * List of services that are scheduled to restart following a crash.
546 */
547 final ArrayList<ServiceRecord> mRestartingServices
548 = new ArrayList<ServiceRecord>();
549
550 /**
551 * List of services that are in the process of being stopped.
552 */
553 final ArrayList<ServiceRecord> mStoppingServices
554 = new ArrayList<ServiceRecord>();
555
556 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700557 * Backup/restore process management
558 */
559 String mBackupAppName = null;
560 BackupRecord mBackupTarget = null;
561
562 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 * List of PendingThumbnailsRecord objects of clients who are still
564 * waiting to receive all of the thumbnails for a task.
565 */
566 final ArrayList mPendingThumbnails = new ArrayList();
567
568 /**
569 * List of HistoryRecord objects that have been finished and must
570 * still report back to a pending thumbnail receiver.
571 */
572 final ArrayList mCancelledThumbnails = new ArrayList();
573
574 /**
575 * All of the currently running global content providers. Keys are a
576 * string containing the provider name and values are a
577 * ContentProviderRecord object containing the data about it. Note
578 * that a single provider may be published under multiple names, so
579 * there may be multiple entries here for a single one in mProvidersByClass.
580 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700581 final HashMap<String, ContentProviderRecord> mProvidersByName
582 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583
584 /**
585 * All of the currently running global content providers. Keys are a
586 * string containing the provider's implementation class and values are a
587 * ContentProviderRecord object containing the data about it.
588 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700589 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
590 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591
592 /**
593 * List of content providers who have clients waiting for them. The
594 * application is currently being launched and the provider will be
595 * removed from this list once it is published.
596 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700597 final ArrayList<ContentProviderRecord> mLaunchingProviders
598 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599
600 /**
601 * Global set of specific Uri permissions that have been granted.
602 */
603 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
604 = new SparseArray<HashMap<Uri, UriPermission>>();
605
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800606 CoreSettingsObserver mCoreSettingsObserver;
607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 /**
609 * Thread-local storage used to carry caller permissions over through
610 * indirect content-provider access.
611 * @see #ActivityManagerService.openContentUri()
612 */
613 private class Identity {
614 public int pid;
615 public int uid;
616
617 Identity(int _pid, int _uid) {
618 pid = _pid;
619 uid = _uid;
620 }
621 }
622 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
623
624 /**
625 * All information we have collected about the runtime performance of
626 * any user id that can impact battery performance.
627 */
628 final BatteryStatsService mBatteryStatsService;
629
630 /**
631 * information about component usage
632 */
633 final UsageStatsService mUsageStatsService;
634
635 /**
636 * Current configuration information. HistoryRecord objects are given
637 * a reference to this object to indicate which configuration they are
638 * currently running in, so this object must be kept immutable.
639 */
640 Configuration mConfiguration = new Configuration();
641
642 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800643 * Current sequencing integer of the configuration, for skipping old
644 * configurations.
645 */
646 int mConfigurationSeq = 0;
647
648 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700649 * Hardware-reported OpenGLES version.
650 */
651 final int GL_ES_VERSION;
652
653 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 * List of initialization arguments to pass to all processes when binding applications to them.
655 * For example, references to the commonly used services.
656 */
657 HashMap<String, IBinder> mAppBindArgs;
658
659 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700660 * Temporary to avoid allocations. Protected by main lock.
661 */
662 final StringBuilder mStringBuilder = new StringBuilder(256);
663
664 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 * Used to control how we initialize the service.
666 */
667 boolean mStartRunning = false;
668 ComponentName mTopComponent;
669 String mTopAction;
670 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700671 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 boolean mSystemReady = false;
673 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700674 boolean mWaitingUpdate = false;
675 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700676 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700677 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678
679 Context mContext;
680
681 int mFactoryTest;
682
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700683 boolean mCheckedForSetup;
684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700686 * The time at which we will allow normal application switches again,
687 * after a call to {@link #stopAppSwitches()}.
688 */
689 long mAppSwitchesAllowedTime;
690
691 /**
692 * This is set to true after the first switch after mAppSwitchesAllowedTime
693 * is set; any switches after that will clear the time.
694 */
695 boolean mDidAppSwitch;
696
697 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700698 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700699 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700700 long mLastPowerCheckRealtime;
701
702 /**
703 * Last time (in uptime) at which we checked for power usage.
704 */
705 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700706
707 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 * Set while we are wanting to sleep, to prevent any
709 * activities from being started/resumed.
710 */
711 boolean mSleeping = false;
712
713 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700714 * Set if we are shutting down the system, similar to sleeping.
715 */
716 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717
718 /**
719 * Task identifier that activities are currently being started
720 * in. Incremented each time a new task is created.
721 * todo: Replace this with a TokenSpace class that generates non-repeating
722 * integers that won't wrap.
723 */
724 int mCurTask = 1;
725
726 /**
727 * Current sequence id for oom_adj computation traversal.
728 */
729 int mAdjSeq = 0;
730
731 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700732 * Current sequence id for process LRU updating.
733 */
734 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735
736 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700737 * Keep track of the number of service processes we last found, to
738 * determine on the next iteration which should be B services.
739 */
740 int mNumServiceProcs = 0;
741 int mNewNumServiceProcs = 0;
742
743 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 * System monitoring: number of processes that died since the last
745 * N procs were started.
746 */
747 int[] mProcDeaths = new int[20];
748
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700749 /**
750 * This is set if we had to do a delayed dexopt of an app before launching
751 * it, to increasing the ANR timeouts in that case.
752 */
753 boolean mDidDexOpt;
754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 String mDebugApp = null;
756 boolean mWaitForDebugger = false;
757 boolean mDebugTransient = false;
758 String mOrigDebugApp = null;
759 boolean mOrigWaitForDebugger = false;
760 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700761 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700762 String mProfileApp = null;
763 ProcessRecord mProfileProc = null;
764 String mProfileFile;
765 ParcelFileDescriptor mProfileFd;
766 int mProfileType = 0;
767 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700769 final RemoteCallbackList<IActivityWatcher> mWatchers
770 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700771
772 final RemoteCallbackList<IProcessObserver> mProcessObservers
773 = new RemoteCallbackList<IProcessObserver>();
774
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 /**
776 * Callback of last caller to {@link #requestPss}.
777 */
778 Runnable mRequestPssCallback;
779
780 /**
781 * Remaining processes for which we are waiting results from the last
782 * call to {@link #requestPss}.
783 */
784 final ArrayList<ProcessRecord> mRequestPssList
785 = new ArrayList<ProcessRecord>();
786
787 /**
788 * Runtime statistics collection thread. This object's lock is used to
789 * protect all related state.
790 */
791 final Thread mProcessStatsThread;
792
793 /**
794 * Used to collect process stats when showing not responding dialog.
795 * Protected by mProcessStatsThread.
796 */
797 final ProcessStats mProcessStats = new ProcessStats(
798 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700799 final AtomicLong mLastCpuTime = new AtomicLong(0);
800 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 long mLastWriteTime = 0;
803
804 /**
805 * Set to true after the system has finished booting.
806 */
807 boolean mBooted = false;
808
Dianne Hackborn7d608422011-08-07 16:24:18 -0700809 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700810 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811
812 WindowManagerService mWindowManager;
813
814 static ActivityManagerService mSelf;
815 static ActivityThread mSystemThread;
816
817 private final class AppDeathRecipient implements IBinder.DeathRecipient {
818 final ProcessRecord mApp;
819 final int mPid;
820 final IApplicationThread mAppThread;
821
822 AppDeathRecipient(ProcessRecord app, int pid,
823 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800824 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 TAG, "New death recipient " + this
826 + " for thread " + thread.asBinder());
827 mApp = app;
828 mPid = pid;
829 mAppThread = thread;
830 }
831
832 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800833 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 TAG, "Death received in " + this
835 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 synchronized(ActivityManagerService.this) {
837 appDiedLocked(mApp, mPid, mAppThread);
838 }
839 }
840 }
841
842 static final int SHOW_ERROR_MSG = 1;
843 static final int SHOW_NOT_RESPONDING_MSG = 2;
844 static final int SHOW_FACTORY_ERROR_MSG = 3;
845 static final int UPDATE_CONFIGURATION_MSG = 4;
846 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
847 static final int WAIT_FOR_DEBUGGER_MSG = 6;
848 static final int BROADCAST_INTENT_MSG = 7;
849 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 static final int SERVICE_TIMEOUT_MSG = 12;
851 static final int UPDATE_TIME_ZONE = 13;
852 static final int SHOW_UID_ERROR_MSG = 14;
853 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700855 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700856 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800857 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700858 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
859 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700860 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700861 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700862 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700863 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700864 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700865 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
866 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700867 static final int REPORT_MEM_USAGE = 33;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868
869 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700870 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700871 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872
873 final Handler mHandler = new Handler() {
874 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800875 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 //}
877
878 public void handleMessage(Message msg) {
879 switch (msg.what) {
880 case SHOW_ERROR_MSG: {
881 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 synchronized (ActivityManagerService.this) {
883 ProcessRecord proc = (ProcessRecord)data.get("app");
884 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800885 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 return;
887 }
888 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700889 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800890 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 d.show();
892 proc.crashDialog = d;
893 } else {
894 // The device is asleep, so just pretend that the user
895 // saw a crash dialog and hit "force quit".
896 res.set(0);
897 }
898 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700899
900 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800901 } break;
902 case SHOW_NOT_RESPONDING_MSG: {
903 synchronized (ActivityManagerService.this) {
904 HashMap data = (HashMap) msg.obj;
905 ProcessRecord proc = (ProcessRecord)data.get("app");
906 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800907 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 return;
909 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800910
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700911 Intent intent = new Intent("android.intent.action.ANR");
912 if (!mProcessesReady) {
913 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
914 }
915 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800916 null, null, 0, null, null, null,
917 false, false, MY_PID, Process.SYSTEM_UID);
918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700920 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 d.show();
922 proc.anrDialog = d;
923 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700924
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700925 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700927 case SHOW_STRICT_MODE_VIOLATION_MSG: {
928 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
929 synchronized (ActivityManagerService.this) {
930 ProcessRecord proc = (ProcessRecord) data.get("app");
931 if (proc == null) {
932 Slog.e(TAG, "App not found when showing strict mode dialog.");
933 break;
934 }
935 if (proc.crashDialog != null) {
936 Slog.e(TAG, "App already has strict mode dialog: " + proc);
937 return;
938 }
939 AppErrorResult res = (AppErrorResult) data.get("result");
940 if (!mSleeping && !mShuttingDown) {
941 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
942 d.show();
943 proc.crashDialog = d;
944 } else {
945 // The device is asleep, so just pretend that the user
946 // saw a crash dialog and hit "force quit".
947 res.set(0);
948 }
949 }
950 ensureBootCompleted();
951 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 case SHOW_FACTORY_ERROR_MSG: {
953 Dialog d = new FactoryErrorDialog(
954 mContext, msg.getData().getCharSequence("msg"));
955 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700956 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 } break;
958 case UPDATE_CONFIGURATION_MSG: {
959 final ContentResolver resolver = mContext.getContentResolver();
960 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
961 } break;
962 case GC_BACKGROUND_PROCESSES_MSG: {
963 synchronized (ActivityManagerService.this) {
964 performAppGcsIfAppropriateLocked();
965 }
966 } break;
967 case WAIT_FOR_DEBUGGER_MSG: {
968 synchronized (ActivityManagerService.this) {
969 ProcessRecord app = (ProcessRecord)msg.obj;
970 if (msg.arg1 != 0) {
971 if (!app.waitedForDebugger) {
972 Dialog d = new AppWaitingForDebuggerDialog(
973 ActivityManagerService.this,
974 mContext, app);
975 app.waitDialog = d;
976 app.waitedForDebugger = true;
977 d.show();
978 }
979 } else {
980 if (app.waitDialog != null) {
981 app.waitDialog.dismiss();
982 app.waitDialog = null;
983 }
984 }
985 }
986 } break;
987 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800988 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 TAG, "Received BROADCAST_INTENT_MSG");
990 processNextBroadcast(true);
991 } break;
992 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700993 synchronized (ActivityManagerService.this) {
994 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800997 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700998 if (mDidDexOpt) {
999 mDidDexOpt = false;
1000 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1001 nmsg.obj = msg.obj;
1002 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1003 return;
1004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 serviceTimeout((ProcessRecord)msg.obj);
1006 } break;
1007 case UPDATE_TIME_ZONE: {
1008 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001009 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1010 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 if (r.thread != null) {
1012 try {
1013 r.thread.updateTimeZone();
1014 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001015 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 }
1017 }
1018 }
1019 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001020 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001021 case CLEAR_DNS_CACHE: {
1022 synchronized (ActivityManagerService.this) {
1023 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1024 ProcessRecord r = mLruProcesses.get(i);
1025 if (r.thread != null) {
1026 try {
1027 r.thread.clearDnsCache();
1028 } catch (RemoteException ex) {
1029 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1030 }
1031 }
1032 }
1033 }
1034 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001035 case UPDATE_HTTP_PROXY: {
1036 ProxyProperties proxy = (ProxyProperties)msg.obj;
1037 String host = "";
1038 String port = "";
1039 String exclList = "";
1040 if (proxy != null) {
1041 host = proxy.getHost();
1042 port = Integer.toString(proxy.getPort());
1043 exclList = proxy.getExclusionList();
1044 }
1045 synchronized (ActivityManagerService.this) {
1046 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1047 ProcessRecord r = mLruProcesses.get(i);
1048 if (r.thread != null) {
1049 try {
1050 r.thread.setHttpProxy(host, port, exclList);
1051 } catch (RemoteException ex) {
1052 Slog.w(TAG, "Failed to update http proxy for: " +
1053 r.info.processName);
1054 }
1055 }
1056 }
1057 }
1058 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001059 case SHOW_UID_ERROR_MSG: {
1060 // XXX This is a temporary dialog, no need to localize.
1061 AlertDialog d = new BaseErrorDialog(mContext);
1062 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1063 d.setCancelable(false);
1064 d.setTitle("System UIDs Inconsistent");
1065 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 +02001066 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1068 mUidAlert = d;
1069 d.show();
1070 } break;
1071 case IM_FEELING_LUCKY_MSG: {
1072 if (mUidAlert != null) {
1073 mUidAlert.dismiss();
1074 mUidAlert = null;
1075 }
1076 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001078 if (mDidDexOpt) {
1079 mDidDexOpt = false;
1080 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1081 nmsg.obj = msg.obj;
1082 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1083 return;
1084 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 ProcessRecord app = (ProcessRecord)msg.obj;
1086 synchronized (ActivityManagerService.this) {
1087 processStartTimedOutLocked(app);
1088 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001089 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001090 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1091 synchronized (ActivityManagerService.this) {
1092 doPendingActivityLaunchesLocked(true);
1093 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001094 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001095 case KILL_APPLICATION_MSG: {
1096 synchronized (ActivityManagerService.this) {
1097 int uid = msg.arg1;
1098 boolean restart = (msg.arg2 == 1);
1099 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001100 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001101 }
1102 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001103 case FINALIZE_PENDING_INTENT_MSG: {
1104 ((PendingIntentRecord)msg.obj).completeFinalize();
1105 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001106 case POST_HEAVY_NOTIFICATION_MSG: {
1107 INotificationManager inm = NotificationManager.getService();
1108 if (inm == null) {
1109 return;
1110 }
1111
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001112 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001113 ProcessRecord process = root.app;
1114 if (process == null) {
1115 return;
1116 }
1117
1118 try {
1119 Context context = mContext.createPackageContext(process.info.packageName, 0);
1120 String text = mContext.getString(R.string.heavy_weight_notification,
1121 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1122 Notification notification = new Notification();
1123 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1124 notification.when = 0;
1125 notification.flags = Notification.FLAG_ONGOING_EVENT;
1126 notification.tickerText = text;
1127 notification.defaults = 0; // please be quiet
1128 notification.sound = null;
1129 notification.vibrate = null;
1130 notification.setLatestEventInfo(context, text,
1131 mContext.getText(R.string.heavy_weight_notification_detail),
1132 PendingIntent.getActivity(mContext, 0, root.intent,
1133 PendingIntent.FLAG_CANCEL_CURRENT));
1134
1135 try {
1136 int[] outId = new int[1];
1137 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1138 notification, outId);
1139 } catch (RuntimeException e) {
1140 Slog.w(ActivityManagerService.TAG,
1141 "Error showing notification for heavy-weight app", e);
1142 } catch (RemoteException e) {
1143 }
1144 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001145 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001146 }
1147 } break;
1148 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1149 INotificationManager inm = NotificationManager.getService();
1150 if (inm == null) {
1151 return;
1152 }
1153 try {
1154 inm.cancelNotification("android",
1155 R.string.heavy_weight_notification);
1156 } catch (RuntimeException e) {
1157 Slog.w(ActivityManagerService.TAG,
1158 "Error canceling notification for service", e);
1159 } catch (RemoteException e) {
1160 }
1161 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001162 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1163 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001164 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001165 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001166 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1167 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001168 }
1169 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001170 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1171 synchronized (ActivityManagerService.this) {
1172 ActivityRecord ar = (ActivityRecord)msg.obj;
1173 if (mCompatModeDialog != null) {
1174 if (mCompatModeDialog.mAppInfo.packageName.equals(
1175 ar.info.applicationInfo.packageName)) {
1176 return;
1177 }
1178 mCompatModeDialog.dismiss();
1179 mCompatModeDialog = null;
1180 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001181 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001182 if (mCompatModePackages.getPackageAskCompatModeLocked(
1183 ar.packageName)) {
1184 int mode = mCompatModePackages.computeCompatModeLocked(
1185 ar.info.applicationInfo);
1186 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1187 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1188 mCompatModeDialog = new CompatModeDialog(
1189 ActivityManagerService.this, mContext,
1190 ar.info.applicationInfo);
1191 mCompatModeDialog.show();
1192 }
1193 }
1194 }
1195 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001196 break;
1197 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001198 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001199 final int pid = msg.arg1;
1200 final int uid = msg.arg2;
1201 final boolean foregroundActivities = (Boolean) msg.obj;
1202 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001203 break;
1204 }
1205 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001206 final int pid = msg.arg1;
1207 final int uid = msg.arg2;
1208 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001209 break;
1210 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001211 case REPORT_MEM_USAGE: {
1212 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1213 if (!isDebuggable) {
1214 return;
1215 }
1216 synchronized (ActivityManagerService.this) {
1217 long now = SystemClock.uptimeMillis();
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001218 if (now < (mLastMemUsageReportTime+5*60*1000)) {
1219 // Don't report more than every 5 minutes to somewhat
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001220 // avoid spamming.
1221 return;
1222 }
1223 mLastMemUsageReportTime = now;
1224 }
1225 Thread thread = new Thread() {
1226 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001227 StringBuilder dropBuilder = new StringBuilder(1024);
1228 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08001229 StringWriter oomSw = new StringWriter();
1230 PrintWriter oomPw = new PrintWriter(oomSw);
1231 StringWriter catSw = new StringWriter();
1232 PrintWriter catPw = new PrintWriter(catSw);
1233 String[] emptyArgs = new String[] { };
1234 StringBuilder tag = new StringBuilder(128);
1235 StringBuilder stack = new StringBuilder(128);
1236 tag.append("Low on memory -- ");
1237 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw,
1238 tag, stack);
1239 dropBuilder.append(stack);
1240 dropBuilder.append('\n');
1241 dropBuilder.append('\n');
1242 String oomString = oomSw.toString();
1243 dropBuilder.append(oomString);
1244 dropBuilder.append('\n');
1245 logBuilder.append(oomString);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001246 try {
1247 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1248 "procrank", });
1249 final InputStreamReader converter = new InputStreamReader(
1250 proc.getInputStream());
1251 BufferedReader in = new BufferedReader(converter);
1252 String line;
1253 while (true) {
1254 line = in.readLine();
1255 if (line == null) {
1256 break;
1257 }
1258 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001259 logBuilder.append(line);
1260 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001261 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001262 dropBuilder.append(line);
1263 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001264 }
1265 converter.close();
1266 } catch (IOException e) {
1267 }
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001268 synchronized (ActivityManagerService.this) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08001269 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001270 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001271 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001272 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001273 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001274 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001275 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001276 dropBuilder.append(catSw.toString());
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001277 addErrorToDropBox("lowmem", null, "system_server", null,
1278 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001279 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001280 synchronized (ActivityManagerService.this) {
1281 long now = SystemClock.uptimeMillis();
1282 if (mLastMemUsageReportTime < now) {
1283 mLastMemUsageReportTime = now;
1284 }
1285 }
1286 }
1287 };
1288 thread.start();
1289 break;
1290 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001291 }
1292 }
1293 };
1294
1295 public static void setSystemProcess() {
1296 try {
1297 ActivityManagerService m = mSelf;
1298
1299 ServiceManager.addService("activity", m);
1300 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001301 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 if (MONITOR_CPU_USAGE) {
1303 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 ServiceManager.addService("permission", new PermissionController(m));
1306
1307 ApplicationInfo info =
1308 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001309 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001310 mSystemThread.installSystemApplicationInfo(info);
1311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001312 synchronized (mSelf) {
1313 ProcessRecord app = mSelf.newProcessRecordLocked(
1314 mSystemThread.getApplicationThread(), info,
1315 info.processName);
1316 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001317 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001318 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1320 synchronized (mSelf.mPidsSelfLocked) {
1321 mSelf.mPidsSelfLocked.put(app.pid, app);
1322 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001323 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 }
1325 } catch (PackageManager.NameNotFoundException e) {
1326 throw new RuntimeException(
1327 "Unable to find android system package", e);
1328 }
1329 }
1330
1331 public void setWindowManager(WindowManagerService wm) {
1332 mWindowManager = wm;
1333 }
1334
1335 public static final Context main(int factoryTest) {
1336 AThread thr = new AThread();
1337 thr.start();
1338
1339 synchronized (thr) {
1340 while (thr.mService == null) {
1341 try {
1342 thr.wait();
1343 } catch (InterruptedException e) {
1344 }
1345 }
1346 }
1347
1348 ActivityManagerService m = thr.mService;
1349 mSelf = m;
1350 ActivityThread at = ActivityThread.systemMain();
1351 mSystemThread = at;
1352 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001353 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001354 m.mContext = context;
1355 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001356 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001357
1358 m.mBatteryStatsService.publish(context);
1359 m.mUsageStatsService.publish(context);
1360
1361 synchronized (thr) {
1362 thr.mReady = true;
1363 thr.notifyAll();
1364 }
1365
1366 m.startRunning(null, null, null, null);
1367
1368 return context;
1369 }
1370
1371 public static ActivityManagerService self() {
1372 return mSelf;
1373 }
1374
1375 static class AThread extends Thread {
1376 ActivityManagerService mService;
1377 boolean mReady = false;
1378
1379 public AThread() {
1380 super("ActivityManager");
1381 }
1382
1383 public void run() {
1384 Looper.prepare();
1385
1386 android.os.Process.setThreadPriority(
1387 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001388 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389
1390 ActivityManagerService m = new ActivityManagerService();
1391
1392 synchronized (this) {
1393 mService = m;
1394 notifyAll();
1395 }
1396
1397 synchronized (this) {
1398 while (!mReady) {
1399 try {
1400 wait();
1401 } catch (InterruptedException e) {
1402 }
1403 }
1404 }
1405
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001406 // For debug builds, log event loop stalls to dropbox for analysis.
1407 if (StrictMode.conditionallyEnableDebugLogging()) {
1408 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1409 }
1410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001411 Looper.loop();
1412 }
1413 }
1414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001415 static class MemBinder extends Binder {
1416 ActivityManagerService mActivityManagerService;
1417 MemBinder(ActivityManagerService activityManagerService) {
1418 mActivityManagerService = activityManagerService;
1419 }
1420
1421 @Override
1422 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001423 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1424 != PackageManager.PERMISSION_GRANTED) {
1425 pw.println("Permission Denial: can't dump meminfo from from pid="
1426 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1427 + " without permission " + android.Manifest.permission.DUMP);
1428 return;
1429 }
1430
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001431 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
Dianne Hackborn672342c2011-11-29 11:29:02 -08001432 false, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001433 }
1434 }
1435
Chet Haase9c1e23b2011-03-24 10:51:31 -07001436 static class GraphicsBinder extends Binder {
1437 ActivityManagerService mActivityManagerService;
1438 GraphicsBinder(ActivityManagerService activityManagerService) {
1439 mActivityManagerService = activityManagerService;
1440 }
1441
1442 @Override
1443 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001444 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1445 != PackageManager.PERMISSION_GRANTED) {
1446 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1447 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1448 + " without permission " + android.Manifest.permission.DUMP);
1449 return;
1450 }
1451
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001452 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001453 }
1454 }
1455
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 static class CpuBinder extends Binder {
1457 ActivityManagerService mActivityManagerService;
1458 CpuBinder(ActivityManagerService activityManagerService) {
1459 mActivityManagerService = activityManagerService;
1460 }
1461
1462 @Override
1463 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001464 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1465 != PackageManager.PERMISSION_GRANTED) {
1466 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1467 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1468 + " without permission " + android.Manifest.permission.DUMP);
1469 return;
1470 }
1471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001473 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1474 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1475 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 }
1477 }
1478 }
1479
1480 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001481 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001482
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 File dataDir = Environment.getDataDirectory();
1484 File systemDir = new File(dataDir, "system");
1485 systemDir.mkdirs();
1486 mBatteryStatsService = new BatteryStatsService(new File(
1487 systemDir, "batterystats.bin").toString());
1488 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001489 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001490 mOnBattery = DEBUG_POWER ? true
1491 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001492 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001494 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001495 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496
Jack Palevichb90d28c2009-07-22 15:35:24 -07001497 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1498 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1499
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001500 mConfiguration.setToDefaults();
1501 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08001502 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 mProcessStats.init();
1504
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001505 mCompatModePackages = new CompatModePackages(this, systemDir);
1506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001507 // Add ourself to the Watchdog monitors.
1508 Watchdog.getInstance().addMonitor(this);
1509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 mProcessStatsThread = new Thread("ProcessStats") {
1511 public void run() {
1512 while (true) {
1513 try {
1514 try {
1515 synchronized(this) {
1516 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001517 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001519 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 // + ", write delay=" + nextWriteDelay);
1521 if (nextWriteDelay < nextCpuDelay) {
1522 nextCpuDelay = nextWriteDelay;
1523 }
1524 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001525 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 this.wait(nextCpuDelay);
1527 }
1528 }
1529 } catch (InterruptedException e) {
1530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 updateCpuStatsNow();
1532 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001533 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 }
1535 }
1536 }
1537 };
1538 mProcessStatsThread.start();
1539 }
1540
1541 @Override
1542 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1543 throws RemoteException {
1544 try {
1545 return super.onTransact(code, data, reply, flags);
1546 } catch (RuntimeException e) {
1547 // The activity manager only throws security exceptions, so let's
1548 // log all others.
1549 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001550 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 }
1552 throw e;
1553 }
1554 }
1555
1556 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001557 final long now = SystemClock.uptimeMillis();
1558 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1559 return;
1560 }
1561 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1562 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 mProcessStatsThread.notify();
1564 }
1565 }
1566 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 void updateCpuStatsNow() {
1569 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001570 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 final long now = SystemClock.uptimeMillis();
1572 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001575 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1576 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001577 haveNewCpuStats = true;
1578 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001579 //Slog.i(TAG, mProcessStats.printCurrentState());
1580 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 // + mProcessStats.getTotalCpuPercent() + "%");
1582
Joe Onorato8a9b2202010-02-26 18:56:32 -08001583 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 if ("true".equals(SystemProperties.get("events.cpu"))) {
1585 int user = mProcessStats.getLastUserTime();
1586 int system = mProcessStats.getLastSystemTime();
1587 int iowait = mProcessStats.getLastIoWaitTime();
1588 int irq = mProcessStats.getLastIrqTime();
1589 int softIrq = mProcessStats.getLastSoftIrqTime();
1590 int idle = mProcessStats.getLastIdleTime();
1591
1592 int total = user + system + iowait + irq + softIrq + idle;
1593 if (total == 0) total = 1;
1594
Doug Zongker2bec3d42009-12-04 12:52:44 -08001595 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001596 ((user+system+iowait+irq+softIrq) * 100) / total,
1597 (user * 100) / total,
1598 (system * 100) / total,
1599 (iowait * 100) / total,
1600 (irq * 100) / total,
1601 (softIrq * 100) / total);
1602 }
1603 }
1604
Amith Yamasanie43530a2009-08-21 13:11:37 -07001605 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001606 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001607 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001608 synchronized(mPidsSelfLocked) {
1609 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001610 if (mOnBattery) {
1611 int perc = bstats.startAddingCpuLocked();
1612 int totalUTime = 0;
1613 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001614 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001615 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001616 ProcessStats.Stats st = mProcessStats.getStats(i);
1617 if (!st.working) {
1618 continue;
1619 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001621 int otherUTime = (st.rel_utime*perc)/100;
1622 int otherSTime = (st.rel_stime*perc)/100;
1623 totalUTime += otherUTime;
1624 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001625 if (pr != null) {
1626 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001627 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1628 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001629 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001630 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001631 } else {
1632 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001633 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001634 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001635 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1636 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001637 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001638 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001639 }
1640 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001641 bstats.finishAddingCpuLocked(perc, totalUTime,
1642 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001643 }
1644 }
1645 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001646
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001647 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1648 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001649 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001650 }
1651 }
1652 }
1653 }
1654
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001655 @Override
1656 public void batteryNeedsCpuUpdate() {
1657 updateCpuStatsNow();
1658 }
1659
1660 @Override
1661 public void batteryPowerChanged(boolean onBattery) {
1662 // When plugging in, update the CPU stats first before changing
1663 // the plug state.
1664 updateCpuStatsNow();
1665 synchronized (this) {
1666 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001667 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001668 }
1669 }
1670 }
1671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001672 /**
1673 * Initialize the application bind args. These are passed to each
1674 * process when the bindApplication() IPC is sent to the process. They're
1675 * lazily setup to make sure the services are running when they're asked for.
1676 */
1677 private HashMap<String, IBinder> getCommonServicesLocked() {
1678 if (mAppBindArgs == null) {
1679 mAppBindArgs = new HashMap<String, IBinder>();
1680
1681 // Setup the application init args
1682 mAppBindArgs.put("package", ServiceManager.getService("package"));
1683 mAppBindArgs.put("window", ServiceManager.getService("window"));
1684 mAppBindArgs.put(Context.ALARM_SERVICE,
1685 ServiceManager.getService(Context.ALARM_SERVICE));
1686 }
1687 return mAppBindArgs;
1688 }
1689
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001690 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001691 if (mFocusedActivity != r) {
1692 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001693 if (r != null) {
1694 mWindowManager.setFocusedApp(r.appToken, true);
1695 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001696 }
1697 }
1698
Dianne Hackborn906497c2010-05-10 15:57:38 -07001699 private final void updateLruProcessInternalLocked(ProcessRecord app,
1700 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001701 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001702 int lrui = mLruProcesses.indexOf(app);
1703 if (lrui >= 0) mLruProcesses.remove(lrui);
1704
1705 int i = mLruProcesses.size()-1;
1706 int skipTop = 0;
1707
Dianne Hackborn906497c2010-05-10 15:57:38 -07001708 app.lruSeq = mLruSeq;
1709
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001710 // compute the new weight for this process.
1711 if (updateActivityTime) {
1712 app.lastActivityTime = SystemClock.uptimeMillis();
1713 }
1714 if (app.activities.size() > 0) {
1715 // If this process has activities, we more strongly want to keep
1716 // it around.
1717 app.lruWeight = app.lastActivityTime;
1718 } else if (app.pubProviders.size() > 0) {
1719 // If this process contains content providers, we want to keep
1720 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001721 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001722 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001723 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001724 } else {
1725 // If this process doesn't have activities, we less strongly
1726 // want to keep it around, and generally want to avoid getting
1727 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001728 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001729 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001730 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001731 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001732
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001733 while (i >= 0) {
1734 ProcessRecord p = mLruProcesses.get(i);
1735 // If this app shouldn't be in front of the first N background
1736 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001737 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001738 skipTop--;
1739 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001740 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001741 mLruProcesses.add(i+1, app);
1742 break;
1743 }
1744 i--;
1745 }
1746 if (i < 0) {
1747 mLruProcesses.add(0, app);
1748 }
1749
Dianne Hackborn906497c2010-05-10 15:57:38 -07001750 // If the app is currently using a content provider or service,
1751 // bump those processes as well.
1752 if (app.connections.size() > 0) {
1753 for (ConnectionRecord cr : app.connections) {
1754 if (cr.binding != null && cr.binding.service != null
1755 && cr.binding.service.app != null
1756 && cr.binding.service.app.lruSeq != mLruSeq) {
1757 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1758 updateActivityTime, i+1);
1759 }
1760 }
1761 }
1762 if (app.conProviders.size() > 0) {
1763 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001764 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1765 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001766 updateActivityTime, i+1);
1767 }
1768 }
1769 }
1770
Joe Onorato8a9b2202010-02-26 18:56:32 -08001771 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001772 if (oomAdj) {
1773 updateOomAdjLocked();
1774 }
1775 }
1776
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001777 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001778 boolean oomAdj, boolean updateActivityTime) {
1779 mLruSeq++;
1780 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1781 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001782
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001783 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 String processName, int uid) {
1785 if (uid == Process.SYSTEM_UID) {
1786 // The system gets to run in any process. If there are multiple
1787 // processes with the same uid, just pick the first (this
1788 // should never happen).
1789 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1790 processName);
1791 return procs != null ? procs.valueAt(0) : null;
1792 }
1793 ProcessRecord proc = mProcessNames.get(processName, uid);
1794 return proc;
1795 }
1796
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001797 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001798 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001799 try {
1800 if (pm.performDexOpt(packageName)) {
1801 mDidDexOpt = true;
1802 }
1803 } catch (RemoteException e) {
1804 }
1805 }
1806
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001807 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 int transit = mWindowManager.getPendingAppTransition();
1809 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1810 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1811 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1812 }
1813
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001814 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001815 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001816 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001817 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1818 // We don't have to do anything more if:
1819 // (1) There is an existing application record; and
1820 // (2) The caller doesn't think it is dead, OR there is no thread
1821 // object attached to it so we know it couldn't have crashed; and
1822 // (3) There is a pid assigned to it, so it is either starting or
1823 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001824 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 + " app=" + app + " knownToBeDead=" + knownToBeDead
1826 + " thread=" + (app != null ? app.thread : null)
1827 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001828 if (app != null && app.pid > 0) {
1829 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001830 // We already have the app running, or are waiting for it to
1831 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001832 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001833 // If this is a new package in the process, add the package to the list
1834 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001835 return app;
1836 } else {
1837 // An application record is attached to a previous process,
1838 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001839 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001840 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001842 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001844 String hostingNameStr = hostingName != null
1845 ? hostingName.flattenToShortString() : null;
1846
1847 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1848 // If we are in the background, then check to see if this process
1849 // is bad. If so, we will just silently fail.
1850 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001851 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1852 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 return null;
1854 }
1855 } else {
1856 // When the user is explicitly starting a process, then clear its
1857 // crash count so that we won't make it bad until they see at
1858 // least one crash dialog again, and make the process good again
1859 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001860 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1861 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001862 mProcessCrashTimes.remove(info.processName, info.uid);
1863 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001864 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865 info.processName);
1866 mBadProcesses.remove(info.processName, info.uid);
1867 if (app != null) {
1868 app.bad = false;
1869 }
1870 }
1871 }
1872
1873 if (app == null) {
1874 app = newProcessRecordLocked(null, info, processName);
1875 mProcessNames.put(processName, info.uid, app);
1876 } else {
1877 // If this is a new package in the process, add the package to the list
1878 app.addPackage(info.packageName);
1879 }
1880
1881 // If the system is not ready yet, then hold off on starting this
1882 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001883 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001884 && !isAllowedWhileBooting(info)
1885 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001886 if (!mProcessesOnHold.contains(app)) {
1887 mProcessesOnHold.add(app);
1888 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001889 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001890 return app;
1891 }
1892
1893 startProcessLocked(app, hostingType, hostingNameStr);
1894 return (app.pid != 0) ? app : null;
1895 }
1896
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001897 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1898 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1899 }
1900
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001901 private final void startProcessLocked(ProcessRecord app,
1902 String hostingType, String hostingNameStr) {
1903 if (app.pid > 0 && app.pid != MY_PID) {
1904 synchronized (mPidsSelfLocked) {
1905 mPidsSelfLocked.remove(app.pid);
1906 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1907 }
1908 app.pid = 0;
1909 }
1910
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001911 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1912 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001913 mProcessesOnHold.remove(app);
1914
1915 updateCpuStats();
1916
1917 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1918 mProcDeaths[0] = 0;
1919
1920 try {
1921 int uid = app.info.uid;
1922 int[] gids = null;
1923 try {
1924 gids = mContext.getPackageManager().getPackageGids(
1925 app.info.packageName);
1926 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001927 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001928 }
1929 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1930 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1931 && mTopComponent != null
1932 && app.processName.equals(mTopComponent.getPackageName())) {
1933 uid = 0;
1934 }
1935 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1936 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1937 uid = 0;
1938 }
1939 }
1940 int debugFlags = 0;
1941 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1942 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001943 // Also turn on CheckJNI for debuggable apps. It's quite
1944 // awkward to turn on otherwise.
1945 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001946 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001947 // Run the app in safe mode if its manifest requests so or the
1948 // system is booted in safe mode.
1949 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1950 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001951 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001953 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1954 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1955 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001956 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1957 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1958 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001959 if ("1".equals(SystemProperties.get("debug.assert"))) {
1960 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1961 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001962
1963 // Start the process. It will either succeed and return a result containing
1964 // the PID of the new process, or else throw a RuntimeException.
1965 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001966 app.processName, uid, uid, gids, debugFlags,
1967 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001969 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1970 synchronized (bs) {
1971 if (bs.isOnBattery()) {
1972 app.batteryStats.incStartsLocked();
1973 }
1974 }
1975
Jeff Brown3f9dd282011-07-08 20:02:19 -07001976 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001977 app.processName, hostingType,
1978 hostingNameStr != null ? hostingNameStr : "");
1979
1980 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001981 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001982 }
1983
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001984 StringBuilder buf = mStringBuilder;
1985 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001986 buf.append("Start proc ");
1987 buf.append(app.processName);
1988 buf.append(" for ");
1989 buf.append(hostingType);
1990 if (hostingNameStr != null) {
1991 buf.append(" ");
1992 buf.append(hostingNameStr);
1993 }
1994 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001995 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001996 buf.append(" uid=");
1997 buf.append(uid);
1998 buf.append(" gids={");
1999 if (gids != null) {
2000 for (int gi=0; gi<gids.length; gi++) {
2001 if (gi != 0) buf.append(", ");
2002 buf.append(gids[gi]);
2003
2004 }
2005 }
2006 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002007 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07002008 app.pid = startResult.pid;
2009 app.usingWrapper = startResult.usingWrapper;
2010 app.removed = false;
2011 synchronized (mPidsSelfLocked) {
2012 this.mPidsSelfLocked.put(startResult.pid, app);
2013 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2014 msg.obj = app;
2015 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2016 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002017 }
2018 } catch (RuntimeException e) {
2019 // XXX do better error recovery.
2020 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002021 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002022 }
2023 }
2024
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002025 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002026 if (resumed) {
2027 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2028 } else {
2029 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2030 }
2031 }
2032
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002033 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002034 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2035 && mTopAction == null) {
2036 // We are running in factory test mode, but unable to find
2037 // the factory test app, so just sit around displaying the
2038 // error message and don't try to start anything.
2039 return false;
2040 }
2041 Intent intent = new Intent(
2042 mTopAction,
2043 mTopData != null ? Uri.parse(mTopData) : null);
2044 intent.setComponent(mTopComponent);
2045 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2046 intent.addCategory(Intent.CATEGORY_HOME);
2047 }
2048 ActivityInfo aInfo =
2049 intent.resolveActivityInfo(mContext.getPackageManager(),
2050 STOCK_PM_FLAGS);
2051 if (aInfo != null) {
2052 intent.setComponent(new ComponentName(
2053 aInfo.applicationInfo.packageName, aInfo.name));
2054 // Don't do this if the home app is currently being
2055 // instrumented.
2056 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2057 aInfo.applicationInfo.uid);
2058 if (app == null || app.instrumentationClass == null) {
2059 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002060 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002061 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002062 }
2063 }
2064
2065
2066 return true;
2067 }
2068
2069 /**
2070 * Starts the "new version setup screen" if appropriate.
2071 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002072 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002073 // Only do this once per boot.
2074 if (mCheckedForSetup) {
2075 return;
2076 }
2077
2078 // We will show this screen if the current one is a different
2079 // version than the last one shown, and we are not running in
2080 // low-level factory test mode.
2081 final ContentResolver resolver = mContext.getContentResolver();
2082 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2083 Settings.Secure.getInt(resolver,
2084 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2085 mCheckedForSetup = true;
2086
2087 // See if we should be showing the platform update setup UI.
2088 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2089 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2090 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2091
2092 // We don't allow third party apps to replace this.
2093 ResolveInfo ri = null;
2094 for (int i=0; ris != null && i<ris.size(); i++) {
2095 if ((ris.get(i).activityInfo.applicationInfo.flags
2096 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2097 ri = ris.get(i);
2098 break;
2099 }
2100 }
2101
2102 if (ri != null) {
2103 String vers = ri.activityInfo.metaData != null
2104 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2105 : null;
2106 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2107 vers = ri.activityInfo.applicationInfo.metaData.getString(
2108 Intent.METADATA_SETUP_VERSION);
2109 }
2110 String lastVers = Settings.Secure.getString(
2111 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2112 if (vers != null && !vers.equals(lastVers)) {
2113 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2114 intent.setComponent(new ComponentName(
2115 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002116 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002117 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002118 }
2119 }
2120 }
2121 }
2122
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002123 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002124 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002125 }
2126
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002127 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002128 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002129 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2130 }
2131 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002132
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002133 public void setFrontActivityScreenCompatMode(int mode) {
2134 synchronized (this) {
2135 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2136 }
2137 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002138
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002139 public int getPackageScreenCompatMode(String packageName) {
2140 synchronized (this) {
2141 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2142 }
2143 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002144
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002145 public void setPackageScreenCompatMode(String packageName, int mode) {
2146 synchronized (this) {
2147 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002148 }
2149 }
2150
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002151 public boolean getPackageAskScreenCompat(String packageName) {
2152 synchronized (this) {
2153 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2154 }
2155 }
2156
2157 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2158 synchronized (this) {
2159 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2160 }
2161 }
2162
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002163 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002164 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002165
2166 final int identHash = System.identityHashCode(r);
2167 updateUsageStats(r, true);
2168
2169 int i = mWatchers.beginBroadcast();
2170 while (i > 0) {
2171 i--;
2172 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2173 if (w != null) {
2174 try {
2175 w.activityResuming(identHash);
2176 } catch (RemoteException e) {
2177 }
2178 }
2179 }
2180 mWatchers.finishBroadcast();
2181 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002182
Jeff Sharkeya4620792011-05-20 15:29:23 -07002183 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2184 int i = mProcessObservers.beginBroadcast();
2185 while (i > 0) {
2186 i--;
2187 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2188 if (observer != null) {
2189 try {
2190 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2191 } catch (RemoteException e) {
2192 }
2193 }
2194 }
2195 mProcessObservers.finishBroadcast();
2196 }
2197
2198 private void dispatchProcessDied(int pid, int uid) {
2199 int i = mProcessObservers.beginBroadcast();
2200 while (i > 0) {
2201 i--;
2202 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2203 if (observer != null) {
2204 try {
2205 observer.onProcessDied(pid, uid);
2206 } catch (RemoteException e) {
2207 }
2208 }
2209 }
2210 mProcessObservers.finishBroadcast();
2211 }
2212
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002213 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002214 final int N = mPendingActivityLaunches.size();
2215 if (N <= 0) {
2216 return;
2217 }
2218 for (int i=0; i<N; i++) {
2219 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002220 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002221 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2222 doResume && i == (N-1));
2223 }
2224 mPendingActivityLaunches.clear();
2225 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002226
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002227 public final int startActivity(IApplicationThread caller,
2228 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2229 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002230 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2231 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002232 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002233 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002234 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2235 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002236 }
2237
2238 public final WaitResult startActivityAndWait(IApplicationThread caller,
2239 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2240 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002241 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2242 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002243 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002244 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002245 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002246 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2247 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002248 return res;
2249 }
2250
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002251 public final int startActivityWithConfig(IApplicationThread caller,
2252 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2253 int grantedMode, IBinder resultTo,
2254 String resultWho, int requestCode, boolean onlyIfNeeded,
2255 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002256 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002257 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002258 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002259 }
2260
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002261 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002262 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002263 IBinder resultTo, String resultWho, int requestCode,
2264 int flagsMask, int flagsValues) {
2265 // Refuse possible leaked file descriptors
2266 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2267 throw new IllegalArgumentException("File descriptors passed in Intent");
2268 }
2269
2270 IIntentSender sender = intent.getTarget();
2271 if (!(sender instanceof PendingIntentRecord)) {
2272 throw new IllegalArgumentException("Bad PendingIntent object");
2273 }
2274
2275 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002276
2277 synchronized (this) {
2278 // If this is coming from the currently resumed activity, it is
2279 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002280 if (mMainStack.mResumedActivity != null
2281 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002282 Binder.getCallingUid()) {
2283 mAppSwitchesAllowedTime = 0;
2284 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002285 }
2286
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002287 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002288 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2289 }
2290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 public boolean startNextMatchingActivity(IBinder callingActivity,
2292 Intent intent) {
2293 // Refuse possible leaked file descriptors
2294 if (intent != null && intent.hasFileDescriptors() == true) {
2295 throw new IllegalArgumentException("File descriptors passed in Intent");
2296 }
2297
2298 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002299 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2300 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002301 return false;
2302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002303 if (r.app == null || r.app.thread == null) {
2304 // The caller is not running... d'oh!
2305 return false;
2306 }
2307 intent = new Intent(intent);
2308 // The caller is not allowed to change the data.
2309 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2310 // And we are resetting to find the next component...
2311 intent.setComponent(null);
2312
2313 ActivityInfo aInfo = null;
2314 try {
2315 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002316 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002318 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319
2320 // Look for the original activity in the list...
2321 final int N = resolves != null ? resolves.size() : 0;
2322 for (int i=0; i<N; i++) {
2323 ResolveInfo rInfo = resolves.get(i);
2324 if (rInfo.activityInfo.packageName.equals(r.packageName)
2325 && rInfo.activityInfo.name.equals(r.info.name)) {
2326 // We found the current one... the next matching is
2327 // after it.
2328 i++;
2329 if (i<N) {
2330 aInfo = resolves.get(i).activityInfo;
2331 }
2332 break;
2333 }
2334 }
2335 } catch (RemoteException e) {
2336 }
2337
2338 if (aInfo == null) {
2339 // Nobody who is next!
2340 return false;
2341 }
2342
2343 intent.setComponent(new ComponentName(
2344 aInfo.applicationInfo.packageName, aInfo.name));
2345 intent.setFlags(intent.getFlags()&~(
2346 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2347 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2348 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2349 Intent.FLAG_ACTIVITY_NEW_TASK));
2350
2351 // Okay now we need to start the new activity, replacing the
2352 // currently running activity. This is a little tricky because
2353 // we want to start the new one as if the current one is finished,
2354 // but not finish the current one first so that there is no flicker.
2355 // And thus...
2356 final boolean wasFinishing = r.finishing;
2357 r.finishing = true;
2358
2359 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002360 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002361 final String resultWho = r.resultWho;
2362 final int requestCode = r.requestCode;
2363 r.resultTo = null;
2364 if (resultTo != null) {
2365 resultTo.removeResultsLocked(r, resultWho, requestCode);
2366 }
2367
2368 final long origId = Binder.clearCallingIdentity();
2369 // XXX we are not dealing with propagating grantedUriPermissions...
2370 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002371 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002372 r.resolvedType, null, 0, aInfo,
2373 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002374 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 Binder.restoreCallingIdentity(origId);
2376
2377 r.finishing = wasFinishing;
2378 if (res != START_SUCCESS) {
2379 return false;
2380 }
2381 return true;
2382 }
2383 }
2384
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002385 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002386 Intent intent, String resolvedType, IBinder resultTo,
2387 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002388
2389 // This is so super not safe, that only the system (or okay root)
2390 // can do it.
2391 final int callingUid = Binder.getCallingUid();
2392 if (callingUid != 0 && callingUid != Process.myUid()) {
2393 throw new SecurityException(
2394 "startActivityInPackage only available to the system");
2395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002397 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002398 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2399 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002400 }
2401
2402 public final int startActivities(IApplicationThread caller,
2403 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2404 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2405 }
2406
2407 public final int startActivitiesInPackage(int uid,
2408 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2409
2410 // This is so super not safe, that only the system (or okay root)
2411 // can do it.
2412 final int callingUid = Binder.getCallingUid();
2413 if (callingUid != 0 && callingUid != Process.myUid()) {
2414 throw new SecurityException(
2415 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002416 }
2417
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002418 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002419 }
2420
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002421 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002422 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002423 // Quick case: check if the top-most recent task is the same.
2424 if (N > 0 && mRecentTasks.get(0) == task) {
2425 return;
2426 }
2427 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002428 for (int i=0; i<N; i++) {
2429 TaskRecord tr = mRecentTasks.get(i);
2430 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2431 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2432 mRecentTasks.remove(i);
2433 i--;
2434 N--;
2435 if (task.intent == null) {
2436 // If the new recent task we are adding is not fully
2437 // specified, then replace it with the existing recent task.
2438 task = tr;
2439 }
2440 }
2441 }
2442 if (N >= MAX_RECENT_TASKS) {
2443 mRecentTasks.remove(N-1);
2444 }
2445 mRecentTasks.add(0, task);
2446 }
2447
2448 public void setRequestedOrientation(IBinder token,
2449 int requestedOrientation) {
2450 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002451 ActivityRecord r = mMainStack.isInStackLocked(token);
2452 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002453 return;
2454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002456 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002458 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002459 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002460 if (config != null) {
2461 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08002462 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002463 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002464 }
2465 }
2466 Binder.restoreCallingIdentity(origId);
2467 }
2468 }
2469
2470 public int getRequestedOrientation(IBinder token) {
2471 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002472 ActivityRecord r = mMainStack.isInStackLocked(token);
2473 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002474 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2475 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002476 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002477 }
2478 }
2479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002480 /**
2481 * This is the internal entry point for handling Activity.finish().
2482 *
2483 * @param token The Binder token referencing the Activity we want to finish.
2484 * @param resultCode Result code, if any, from this Activity.
2485 * @param resultData Result data (Intent), if any, from this Activity.
2486 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002487 * @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 -08002488 */
2489 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2490 // Refuse possible leaked file descriptors
2491 if (resultData != null && resultData.hasFileDescriptors() == true) {
2492 throw new IllegalArgumentException("File descriptors passed in Intent");
2493 }
2494
2495 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002496 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002497 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002498 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002499 if (next != null) {
2500 // ask watcher if this is allowed
2501 boolean resumeOK = true;
2502 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002503 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002504 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002505 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 }
2507
2508 if (!resumeOK) {
2509 return false;
2510 }
2511 }
2512 }
2513 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002514 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002515 resultData, "app-request");
2516 Binder.restoreCallingIdentity(origId);
2517 return res;
2518 }
2519 }
2520
Dianne Hackborn860755f2010-06-03 18:47:52 -07002521 public final void finishHeavyWeightApp() {
2522 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2523 != PackageManager.PERMISSION_GRANTED) {
2524 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2525 + Binder.getCallingPid()
2526 + ", uid=" + Binder.getCallingUid()
2527 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2528 Slog.w(TAG, msg);
2529 throw new SecurityException(msg);
2530 }
2531
2532 synchronized(this) {
2533 if (mHeavyWeightProcess == null) {
2534 return;
2535 }
2536
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002537 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002538 mHeavyWeightProcess.activities);
2539 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002540 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002541 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002542 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002543 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002544 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002545 null, "finish-heavy");
2546 }
2547 }
2548 }
2549
2550 mHeavyWeightProcess = null;
2551 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2552 }
2553 }
2554
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002555 public void crashApplication(int uid, int initialPid, String packageName,
2556 String message) {
2557 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2558 != PackageManager.PERMISSION_GRANTED) {
2559 String msg = "Permission Denial: crashApplication() from pid="
2560 + Binder.getCallingPid()
2561 + ", uid=" + Binder.getCallingUid()
2562 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2563 Slog.w(TAG, msg);
2564 throw new SecurityException(msg);
2565 }
2566
2567 synchronized(this) {
2568 ProcessRecord proc = null;
2569
2570 // Figure out which process to kill. We don't trust that initialPid
2571 // still has any relation to current pids, so must scan through the
2572 // list.
2573 synchronized (mPidsSelfLocked) {
2574 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2575 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2576 if (p.info.uid != uid) {
2577 continue;
2578 }
2579 if (p.pid == initialPid) {
2580 proc = p;
2581 break;
2582 }
2583 for (String str : p.pkgList) {
2584 if (str.equals(packageName)) {
2585 proc = p;
2586 }
2587 }
2588 }
2589 }
2590
2591 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002592 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002593 + " initialPid=" + initialPid
2594 + " packageName=" + packageName);
2595 return;
2596 }
2597
2598 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002599 if (proc.pid == Process.myPid()) {
2600 Log.w(TAG, "crashApplication: trying to crash self!");
2601 return;
2602 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002603 long ident = Binder.clearCallingIdentity();
2604 try {
2605 proc.thread.scheduleCrash(message);
2606 } catch (RemoteException e) {
2607 }
2608 Binder.restoreCallingIdentity(ident);
2609 }
2610 }
2611 }
2612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 public final void finishSubActivity(IBinder token, String resultWho,
2614 int requestCode) {
2615 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002616 ActivityRecord self = mMainStack.isInStackLocked(token);
2617 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002618 return;
2619 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002620
2621 final long origId = Binder.clearCallingIdentity();
2622
2623 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002624 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2625 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002626 if (r.resultTo == self && r.requestCode == requestCode) {
2627 if ((r.resultWho == null && resultWho == null) ||
2628 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002629 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 Activity.RESULT_CANCELED, null, "request-sub");
2631 }
2632 }
2633 }
2634
2635 Binder.restoreCallingIdentity(origId);
2636 }
2637 }
2638
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002639 public boolean willActivityBeVisible(IBinder token) {
2640 synchronized(this) {
2641 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002642 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2643 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002644 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002645 return true;
2646 }
2647 if (r.fullscreen && !r.finishing) {
2648 return false;
2649 }
2650 }
2651 return true;
2652 }
2653 }
2654
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002655 public void overridePendingTransition(IBinder token, String packageName,
2656 int enterAnim, int exitAnim) {
2657 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002658 ActivityRecord self = mMainStack.isInStackLocked(token);
2659 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002660 return;
2661 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002662
2663 final long origId = Binder.clearCallingIdentity();
2664
2665 if (self.state == ActivityState.RESUMED
2666 || self.state == ActivityState.PAUSING) {
2667 mWindowManager.overridePendingAppTransition(packageName,
2668 enterAnim, exitAnim);
2669 }
2670
2671 Binder.restoreCallingIdentity(origId);
2672 }
2673 }
2674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002675 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002676 * Main function for removing an existing process from the activity manager
2677 * as a result of that process going away. Clears out all connections
2678 * to the process.
2679 */
2680 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002681 boolean restarting, boolean allowRestart) {
2682 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002683 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002684 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 }
2686
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002687 if (mProfileProc == app) {
2688 clearProfilerLocked();
2689 }
2690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002691 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002692 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2693 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2694 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002695 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002696 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2697 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 }
2699
2700 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002701 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002702
2703 boolean atTop = true;
2704 boolean hasVisibleActivities = false;
2705
2706 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002707 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002708 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709 TAG, "Removing app " + app + " from history with " + i + " entries");
2710 while (i > 0) {
2711 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002712 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002713 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002714 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2715 if (r.app == app) {
2716 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002717 if (ActivityStack.DEBUG_ADD_REMOVE) {
2718 RuntimeException here = new RuntimeException("here");
2719 here.fillInStackTrace();
2720 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2721 + ": haveState=" + r.haveState
2722 + " stateNotNeeded=" + r.stateNotNeeded
2723 + " finishing=" + r.finishing
2724 + " state=" + r.state, here);
2725 }
2726 if (!r.finishing) {
2727 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -08002728 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2729 System.identityHashCode(r),
2730 r.task.taskId, r.shortComponentName,
2731 "proc died without state saved");
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002732 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002733 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002734 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002735 r.takeFromHistory();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002736 mWindowManager.removeAppToken(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002737 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002738 mMainStack.validateAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002740 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002741
2742 } else {
2743 // We have the current state for this activity, so
2744 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002745 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002746 TAG, "Keeping entry, setting app to null");
2747 if (r.visible) {
2748 hasVisibleActivities = true;
2749 }
2750 r.app = null;
2751 r.nowVisible = false;
2752 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002753 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2754 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002755 r.icicle = null;
2756 }
2757 }
2758
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002759 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002760 }
2761 atTop = false;
2762 }
2763
2764 app.activities.clear();
2765
2766 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002767 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002768 + " running instrumentation " + app.instrumentationClass);
2769 Bundle info = new Bundle();
2770 info.putString("shortMsg", "Process crashed.");
2771 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2772 }
2773
2774 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002775 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002776 // If there was nothing to resume, and we are not already
2777 // restarting this process, but there is a visible activity that
2778 // is hosted by the process... then make sure all visible
2779 // activities are running, taking care of restarting this
2780 // process.
2781 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002782 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002783 }
2784 }
2785 }
2786 }
2787
2788 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2789 IBinder threadBinder = thread.asBinder();
2790
2791 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002792 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2793 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002794 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2795 return i;
2796 }
2797 }
2798 return -1;
2799 }
2800
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002801 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002802 IApplicationThread thread) {
2803 if (thread == null) {
2804 return null;
2805 }
2806
2807 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002808 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002809 }
2810
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002811 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002812 IApplicationThread thread) {
2813
2814 mProcDeaths[0]++;
2815
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002816 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2817 synchronized (stats) {
2818 stats.noteProcessDiedLocked(app.info.uid, pid);
2819 }
2820
Magnus Edlund7bb25812010-02-24 15:45:06 +01002821 // Clean up already done if the process has been re-started.
2822 if (app.pid == pid && app.thread != null &&
2823 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002824 if (!app.killedBackground) {
2825 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2826 + ") has died.");
2827 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002828 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002829 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002830 TAG, "Dying app: " + app + ", pid: " + pid
2831 + ", thread: " + thread.asBinder());
2832 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002833 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002834
2835 if (doLowMem) {
2836 // If there are no longer any background processes running,
2837 // and the app that died was not running instrumentation,
2838 // then tell everyone we are now low on memory.
2839 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002840 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2841 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002842 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 haveBg = true;
2844 break;
2845 }
2846 }
2847
2848 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002849 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002850 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002851 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2852 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002853 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002854 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2855 // The low memory report is overriding any current
2856 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002857 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002858 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002859 rec.lastRequestedGc = 0;
2860 } else {
2861 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002862 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002863 rec.reportLowMemory = true;
2864 rec.lastLowMemory = now;
2865 mProcessesToGc.remove(rec);
2866 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002867 }
2868 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002869 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002870 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002871 }
2872 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002873 } else if (app.pid != pid) {
2874 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002875 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002876 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002877 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002878 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002879 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002880 + thread.asBinder());
2881 }
2882 }
2883
Dan Egnor42471dd2010-01-07 17:25:22 -08002884 /**
2885 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002886 * @param clearTraces causes the dump file to be erased prior to the new
2887 * traces being written, if true; when false, the new traces will be
2888 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002889 * @param firstPids of dalvik VM processes to dump stack traces for first
2890 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002891 * @return file containing stack traces, or null if no dump file is configured
2892 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002893 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2894 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002895 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2896 if (tracesPath == null || tracesPath.length() == 0) {
2897 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002898 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002899
2900 File tracesFile = new File(tracesPath);
2901 try {
2902 File tracesDir = tracesFile.getParentFile();
2903 if (!tracesDir.exists()) tracesFile.mkdirs();
2904 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2905
Christopher Tate6ee412d2010-05-28 12:01:56 -07002906 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002907 tracesFile.createNewFile();
2908 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2909 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002910 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002911 return null;
2912 }
2913
2914 // Use a FileObserver to detect when traces finish writing.
2915 // The order of traces is considered important to maintain for legibility.
2916 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2917 public synchronized void onEvent(int event, String path) { notify(); }
2918 };
2919
2920 try {
2921 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002922
2923 // First collect all of the stacks of the most important pids.
2924 try {
2925 int num = firstPids.size();
2926 for (int i = 0; i < num; i++) {
2927 synchronized (observer) {
2928 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2929 observer.wait(200); // Wait for write-close, give up after 200msec
2930 }
2931 }
2932 } catch (InterruptedException e) {
2933 Log.wtf(TAG, e);
2934 }
2935
2936 // Next measure CPU usage.
2937 if (processStats != null) {
2938 processStats.init();
2939 System.gc();
2940 processStats.update();
2941 try {
2942 synchronized (processStats) {
2943 processStats.wait(500); // measure over 1/2 second.
2944 }
2945 } catch (InterruptedException e) {
2946 }
2947 processStats.update();
2948
2949 // We'll take the stack crawls of just the top apps using CPU.
2950 final int N = processStats.countWorkingStats();
2951 int numProcs = 0;
2952 for (int i=0; i<N && numProcs<5; i++) {
2953 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2954 if (lastPids.indexOfKey(stats.pid) >= 0) {
2955 numProcs++;
2956 try {
2957 synchronized (observer) {
2958 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2959 observer.wait(200); // Wait for write-close, give up after 200msec
2960 }
2961 } catch (InterruptedException e) {
2962 Log.wtf(TAG, e);
2963 }
2964
2965 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002966 }
2967 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002968
2969 return tracesFile;
2970
Dan Egnor42471dd2010-01-07 17:25:22 -08002971 } finally {
2972 observer.stopWatching();
2973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002974 }
2975
Jeff Brown4d94a762010-09-23 11:33:28 -07002976 private final class AppNotResponding implements Runnable {
2977 private final ProcessRecord mApp;
2978 private final String mAnnotation;
2979
2980 public AppNotResponding(ProcessRecord app, String annotation) {
2981 mApp = app;
2982 mAnnotation = annotation;
2983 }
2984
2985 @Override
2986 public void run() {
2987 appNotResponding(mApp, null, null, mAnnotation);
2988 }
2989 }
2990
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002991 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2992 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002993 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2994 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2995
Dianne Hackborn287952c2010-09-22 22:34:31 -07002996 if (mController != null) {
2997 try {
2998 // 0 == continue, -1 = kill process immediately
2999 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3000 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3001 } catch (RemoteException e) {
3002 mController = null;
3003 }
3004 }
3005
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003006 long anrTime = SystemClock.uptimeMillis();
3007 if (MONITOR_CPU_USAGE) {
3008 updateCpuStatsNow();
3009 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003010
3011 synchronized (this) {
3012 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3013 if (mShuttingDown) {
3014 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3015 return;
3016 } else if (app.notResponding) {
3017 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3018 return;
3019 } else if (app.crashing) {
3020 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3021 return;
3022 }
3023
3024 // In case we come through here for the same app before completing
3025 // this one, mark as anring now so we will bail out.
3026 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003027
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003028 // Log the ANR to the event log.
3029 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3030 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003031
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003032 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003033 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003034
3035 int parentPid = app.pid;
3036 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003037 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003038
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003039 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003040
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003041 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3042 ProcessRecord r = mLruProcesses.get(i);
3043 if (r != null && r.thread != null) {
3044 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003045 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3046 if (r.persistent) {
3047 firstPids.add(pid);
3048 } else {
3049 lastPids.put(pid, Boolean.TRUE);
3050 }
3051 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003052 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 }
3054 }
3055
Dan Egnor42471dd2010-01-07 17:25:22 -08003056 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003057 StringBuilder info = mStringBuilder;
3058 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003059 info.append("ANR in ").append(app.processName);
3060 if (activity != null && activity.shortComponentName != null) {
3061 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003062 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003063 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003064 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003065 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003066 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003067 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003068 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003070
Dianne Hackborn287952c2010-09-22 22:34:31 -07003071 final ProcessStats processStats = new ProcessStats(true);
3072
3073 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3074
Dan Egnor42471dd2010-01-07 17:25:22 -08003075 String cpuInfo = null;
3076 if (MONITOR_CPU_USAGE) {
3077 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003078 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003079 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003080 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003081 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003082 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003083 }
3084
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003085 info.append(processStats.printCurrentState(anrTime));
3086
Joe Onorato8a9b2202010-02-26 18:56:32 -08003087 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003088 if (tracesFile == null) {
3089 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3090 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3091 }
3092
Jeff Sharkeya353d262011-10-28 11:12:06 -07003093 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3094 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003095
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003096 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003097 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003098 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3099 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003100 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003101 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3102 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003103 }
3104 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003105 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003106 }
3107 }
3108
Dan Egnor42471dd2010-01-07 17:25:22 -08003109 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3110 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3111 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003112
3113 synchronized (this) {
3114 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003115 Slog.w(TAG, "Killing " + app + ": background ANR");
3116 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3117 app.processName, app.setAdj, "background ANR");
3118 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003119 return;
3120 }
3121
3122 // Set the app's notResponding state, and look up the errorReportReceiver
3123 makeAppNotRespondingLocked(app,
3124 activity != null ? activity.shortComponentName : null,
3125 annotation != null ? "ANR " + annotation : "ANR",
3126 info.toString());
3127
3128 // Bring up the infamous App Not Responding dialog
3129 Message msg = Message.obtain();
3130 HashMap map = new HashMap();
3131 msg.what = SHOW_NOT_RESPONDING_MSG;
3132 msg.obj = map;
3133 map.put("app", app);
3134 if (activity != null) {
3135 map.put("activity", activity);
3136 }
3137
3138 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003139 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003140 }
3141
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003142 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3143 if (!mLaunchWarningShown) {
3144 mLaunchWarningShown = true;
3145 mHandler.post(new Runnable() {
3146 @Override
3147 public void run() {
3148 synchronized (ActivityManagerService.this) {
3149 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3150 d.show();
3151 mHandler.postDelayed(new Runnable() {
3152 @Override
3153 public void run() {
3154 synchronized (ActivityManagerService.this) {
3155 d.dismiss();
3156 mLaunchWarningShown = false;
3157 }
3158 }
3159 }, 4000);
3160 }
3161 }
3162 });
3163 }
3164 }
3165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003166 public boolean clearApplicationUserData(final String packageName,
3167 final IPackageDataObserver observer) {
3168 int uid = Binder.getCallingUid();
3169 int pid = Binder.getCallingPid();
3170 long callingId = Binder.clearCallingIdentity();
3171 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003172 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003173 int pkgUid = -1;
3174 synchronized(this) {
3175 try {
3176 pkgUid = pm.getPackageUid(packageName);
3177 } catch (RemoteException e) {
3178 }
3179 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003180 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003181 return false;
3182 }
3183 if (uid == pkgUid || checkComponentPermission(
3184 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003185 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003186 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003187 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003188 } else {
3189 throw new SecurityException(pid+" does not have permission:"+
3190 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3191 "for process:"+packageName);
3192 }
3193 }
3194
3195 try {
3196 //clear application user data
3197 pm.clearApplicationUserData(packageName, observer);
3198 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3199 Uri.fromParts("package", packageName, null));
3200 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003201 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3202 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003203 } catch (RemoteException e) {
3204 }
3205 } finally {
3206 Binder.restoreCallingIdentity(callingId);
3207 }
3208 return true;
3209 }
3210
Dianne Hackborn03abb812010-01-04 18:43:19 -08003211 public void killBackgroundProcesses(final String packageName) {
3212 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3213 != PackageManager.PERMISSION_GRANTED &&
3214 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3215 != PackageManager.PERMISSION_GRANTED) {
3216 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003217 + Binder.getCallingPid()
3218 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003219 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003220 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003221 throw new SecurityException(msg);
3222 }
3223
3224 long callingId = Binder.clearCallingIdentity();
3225 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003226 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003227 int pkgUid = -1;
3228 synchronized(this) {
3229 try {
3230 pkgUid = pm.getPackageUid(packageName);
3231 } catch (RemoteException e) {
3232 }
3233 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003234 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003235 return;
3236 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003237 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003238 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3239 }
3240 } finally {
3241 Binder.restoreCallingIdentity(callingId);
3242 }
3243 }
3244
3245 public void killAllBackgroundProcesses() {
3246 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3247 != PackageManager.PERMISSION_GRANTED) {
3248 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3249 + Binder.getCallingPid()
3250 + ", uid=" + Binder.getCallingUid()
3251 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3252 Slog.w(TAG, msg);
3253 throw new SecurityException(msg);
3254 }
3255
3256 long callingId = Binder.clearCallingIdentity();
3257 try {
3258 synchronized(this) {
3259 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3260 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3261 final int NA = apps.size();
3262 for (int ia=0; ia<NA; ia++) {
3263 ProcessRecord app = apps.valueAt(ia);
3264 if (app.persistent) {
3265 // we don't kill persistent processes
3266 continue;
3267 }
3268 if (app.removed) {
3269 procs.add(app);
3270 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3271 app.removed = true;
3272 procs.add(app);
3273 }
3274 }
3275 }
3276
3277 int N = procs.size();
3278 for (int i=0; i<N; i++) {
3279 removeProcessLocked(procs.get(i), false, true, "kill all background");
3280 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003281 }
3282 } finally {
3283 Binder.restoreCallingIdentity(callingId);
3284 }
3285 }
3286
3287 public void forceStopPackage(final String packageName) {
3288 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3289 != PackageManager.PERMISSION_GRANTED) {
3290 String msg = "Permission Denial: forceStopPackage() from pid="
3291 + Binder.getCallingPid()
3292 + ", uid=" + Binder.getCallingUid()
3293 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003294 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003295 throw new SecurityException(msg);
3296 }
3297
3298 long callingId = Binder.clearCallingIdentity();
3299 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003300 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003301 int pkgUid = -1;
3302 synchronized(this) {
3303 try {
3304 pkgUid = pm.getPackageUid(packageName);
3305 } catch (RemoteException e) {
3306 }
3307 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003308 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003309 return;
3310 }
3311 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003312 try {
3313 pm.setPackageStoppedState(packageName, true);
3314 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003315 } catch (IllegalArgumentException e) {
3316 Slog.w(TAG, "Failed trying to unstop package "
3317 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003319 }
3320 } finally {
3321 Binder.restoreCallingIdentity(callingId);
3322 }
3323 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003324
3325 /*
3326 * The pkg name and uid have to be specified.
3327 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3328 */
3329 public void killApplicationWithUid(String pkg, int uid) {
3330 if (pkg == null) {
3331 return;
3332 }
3333 // Make sure the uid is valid.
3334 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003335 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003336 return;
3337 }
3338 int callerUid = Binder.getCallingUid();
3339 // Only the system server can kill an application
3340 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003341 // Post an aysnc message to kill the application
3342 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3343 msg.arg1 = uid;
3344 msg.arg2 = 0;
3345 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003346 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003347 } else {
3348 throw new SecurityException(callerUid + " cannot kill pkg: " +
3349 pkg);
3350 }
3351 }
3352
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003353 public void closeSystemDialogs(String reason) {
3354 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003355 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003356 if (reason != null) {
3357 intent.putExtra("reason", reason);
3358 }
3359
3360 final int uid = Binder.getCallingUid();
3361 final long origId = Binder.clearCallingIdentity();
3362 synchronized (this) {
3363 int i = mWatchers.beginBroadcast();
3364 while (i > 0) {
3365 i--;
3366 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3367 if (w != null) {
3368 try {
3369 w.closingSystemDialogs(reason);
3370 } catch (RemoteException e) {
3371 }
3372 }
3373 }
3374 mWatchers.finishBroadcast();
3375
Dianne Hackbornffa42482009-09-23 22:20:11 -07003376 mWindowManager.closeSystemDialogs(reason);
3377
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003378 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3379 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003380 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003381 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003382 Activity.RESULT_CANCELED, null, "close-sys");
3383 }
3384 }
3385
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003386 broadcastIntentLocked(null, null, intent, null,
3387 null, 0, null, null, null, false, false, -1, uid);
3388 }
3389 Binder.restoreCallingIdentity(origId);
3390 }
3391
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003392 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003393 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003394 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3395 for (int i=pids.length-1; i>=0; i--) {
3396 infos[i] = new Debug.MemoryInfo();
3397 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003398 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003399 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003400 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003401
Dianne Hackbornb437e092011-08-05 17:50:29 -07003402 public long[] getProcessPss(int[] pids) throws RemoteException {
3403 long[] pss = new long[pids.length];
3404 for (int i=pids.length-1; i>=0; i--) {
3405 pss[i] = Debug.getPss(pids[i]);
3406 }
3407 return pss;
3408 }
3409
Christopher Tate5e1ab332009-09-01 20:32:49 -07003410 public void killApplicationProcess(String processName, int uid) {
3411 if (processName == null) {
3412 return;
3413 }
3414
3415 int callerUid = Binder.getCallingUid();
3416 // Only the system server can kill an application
3417 if (callerUid == Process.SYSTEM_UID) {
3418 synchronized (this) {
3419 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003420 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003421 try {
3422 app.thread.scheduleSuicide();
3423 } catch (RemoteException e) {
3424 // If the other end already died, then our work here is done.
3425 }
3426 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003427 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003428 + processName + " / " + uid);
3429 }
3430 }
3431 } else {
3432 throw new SecurityException(callerUid + " cannot kill app process: " +
3433 processName);
3434 }
3435 }
3436
Dianne Hackborn03abb812010-01-04 18:43:19 -08003437 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003438 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003439 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3440 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003441 if (!mProcessesReady) {
3442 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3443 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003444 intent.putExtra(Intent.EXTRA_UID, uid);
3445 broadcastIntentLocked(null, null, intent,
3446 null, null, 0, null, null, null,
3447 false, false, MY_PID, Process.SYSTEM_UID);
3448 }
3449
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003450 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003451 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003452 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003453 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003454
Dianne Hackborn03abb812010-01-04 18:43:19 -08003455 // Remove all processes this package may have touched: all with the
3456 // same UID (except for the system or root user), and all whose name
3457 // matches the package name.
3458 final String procNamePrefix = packageName + ":";
3459 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3460 final int NA = apps.size();
3461 for (int ia=0; ia<NA; ia++) {
3462 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003463 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003464 // we don't kill persistent processes
3465 continue;
3466 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003467 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003468 if (doit) {
3469 procs.add(app);
3470 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003471 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3472 || app.processName.equals(packageName)
3473 || app.processName.startsWith(procNamePrefix)) {
3474 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003475 if (!doit) {
3476 return true;
3477 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003478 app.removed = true;
3479 procs.add(app);
3480 }
3481 }
3482 }
3483 }
3484
3485 int N = procs.size();
3486 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003487 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003488 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003489 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003490 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003491
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003492 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003493 boolean callerWillRestart, boolean purgeCache, boolean doit,
3494 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003495 int i;
3496 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003498 if (uid < 0) {
3499 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003500 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003501 } catch (RemoteException e) {
3502 }
3503 }
3504
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003505 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003506 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003507
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003508 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3509 while (badApps.hasNext()) {
3510 SparseArray<Long> ba = badApps.next();
3511 if (ba.get(uid) != null) {
3512 badApps.remove();
3513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003514 }
3515 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003516
3517 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003518 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003519
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003520 TaskRecord lastTask = null;
3521 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003522 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003523 final boolean samePackage = r.packageName.equals(name);
3524 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003525 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003526 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003527 if (r.finishing) {
3528 // If this activity is just finishing, then it is not
3529 // interesting as far as something to stop.
3530 continue;
3531 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003532 return true;
3533 }
3534 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003535 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003536 if (samePackage) {
3537 if (r.app != null) {
3538 r.app.removed = true;
3539 }
3540 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003542 lastTask = r.task;
3543 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3544 null, "force-stop")) {
3545 i--;
3546 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003547 }
3548 }
3549
3550 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3551 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003552 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003553 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003554 if (!doit) {
3555 return true;
3556 }
3557 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003558 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003559 if (service.app != null) {
3560 service.app.removed = true;
3561 }
3562 service.app = null;
3563 services.add(service);
3564 }
3565 }
3566
3567 N = services.size();
3568 for (i=0; i<N; i++) {
3569 bringDownServiceLocked(services.get(i), true);
3570 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003571
3572 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3573 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3574 if (provider.info.packageName.equals(name)
3575 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3576 if (!doit) {
3577 return true;
3578 }
3579 didSomething = true;
3580 providers.add(provider);
3581 }
3582 }
3583
3584 N = providers.size();
3585 for (i=0; i<N; i++) {
3586 removeDyingProviderLocked(null, providers.get(i));
3587 }
3588
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003589 if (doit) {
3590 if (purgeCache) {
3591 AttributeCache ac = AttributeCache.instance();
3592 if (ac != null) {
3593 ac.removePackage(name);
3594 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003595 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003596 if (mBooted) {
3597 mMainStack.resumeTopActivityLocked(null);
3598 mMainStack.scheduleIdleLocked();
3599 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003600 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003601
3602 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003603 }
3604
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003605 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003606 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607 final String name = app.processName;
3608 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003609 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003610 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003611 + "/" + uid + ")");
3612
3613 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003614 if (mHeavyWeightProcess == app) {
3615 mHeavyWeightProcess = null;
3616 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003618 boolean needRestart = false;
3619 if (app.pid > 0 && app.pid != MY_PID) {
3620 int pid = app.pid;
3621 synchronized (mPidsSelfLocked) {
3622 mPidsSelfLocked.remove(pid);
3623 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3624 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003625 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003626 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003627 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003628 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629
3630 if (app.persistent) {
3631 if (!callerWillRestart) {
3632 addAppLocked(app.info);
3633 } else {
3634 needRestart = true;
3635 }
3636 }
3637 } else {
3638 mRemovedProcesses.add(app);
3639 }
3640
3641 return needRestart;
3642 }
3643
3644 private final void processStartTimedOutLocked(ProcessRecord app) {
3645 final int pid = app.pid;
3646 boolean gone = false;
3647 synchronized (mPidsSelfLocked) {
3648 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3649 if (knownApp != null && knownApp.thread == null) {
3650 mPidsSelfLocked.remove(pid);
3651 gone = true;
3652 }
3653 }
3654
3655 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003656 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003657 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003658 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003659 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003660 if (mHeavyWeightProcess == app) {
3661 mHeavyWeightProcess = null;
3662 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3663 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003664 // Take care of any launching providers waiting for this process.
3665 checkAppInLaunchingProvidersLocked(app, true);
3666 // Take care of any services that are waiting for the process.
3667 for (int i=0; i<mPendingServices.size(); i++) {
3668 ServiceRecord sr = mPendingServices.get(i);
3669 if (app.info.uid == sr.appInfo.uid
3670 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003671 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003672 mPendingServices.remove(i);
3673 i--;
3674 bringDownServiceLocked(sr, true);
3675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003676 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003677 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3678 app.processName, app.setAdj, "start timeout");
3679 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003680 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003681 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003682 try {
3683 IBackupManager bm = IBackupManager.Stub.asInterface(
3684 ServiceManager.getService(Context.BACKUP_SERVICE));
3685 bm.agentDisconnected(app.info.packageName);
3686 } catch (RemoteException e) {
3687 // Can't happen; the backup manager is local
3688 }
3689 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003690 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003691 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003692 mPendingBroadcast.state = BroadcastRecord.IDLE;
3693 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003694 mPendingBroadcast = null;
3695 scheduleBroadcastsLocked();
3696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003697 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003698 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003699 }
3700 }
3701
3702 private final boolean attachApplicationLocked(IApplicationThread thread,
3703 int pid) {
3704
3705 // Find the application record that is being attached... either via
3706 // the pid if we are running in multiple processes, or just pull the
3707 // next app record if we are emulating process with anonymous threads.
3708 ProcessRecord app;
3709 if (pid != MY_PID && pid >= 0) {
3710 synchronized (mPidsSelfLocked) {
3711 app = mPidsSelfLocked.get(pid);
3712 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713 } else {
3714 app = null;
3715 }
3716
3717 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003718 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003719 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003720 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003721 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003722 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003723 } else {
3724 try {
3725 thread.scheduleExit();
3726 } catch (Exception e) {
3727 // Ignore exceptions.
3728 }
3729 }
3730 return false;
3731 }
3732
3733 // If this application record is still attached to a previous
3734 // process, clean it up now.
3735 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003736 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003737 }
3738
3739 // Tell the process all about itself.
3740
Joe Onorato8a9b2202010-02-26 18:56:32 -08003741 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003742 TAG, "Binding process pid " + pid + " to record " + app);
3743
3744 String processName = app.processName;
3745 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003746 AppDeathRecipient adr = new AppDeathRecipient(
3747 app, pid, thread);
3748 thread.asBinder().linkToDeath(adr, 0);
3749 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003750 } catch (RemoteException e) {
3751 app.resetPackageList();
3752 startProcessLocked(app, "link fail", processName);
3753 return false;
3754 }
3755
Doug Zongker2bec3d42009-12-04 12:52:44 -08003756 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003757
3758 app.thread = thread;
3759 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003760 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3761 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003762 app.forcingToForeground = null;
3763 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003764 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003765 app.debugging = false;
3766
3767 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3768
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003769 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003770 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003771
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003772 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003773 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003774 }
3775
Joe Onorato8a9b2202010-02-26 18:56:32 -08003776 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003777 TAG, "New app record " + app
3778 + " thread=" + thread.asBinder() + " pid=" + pid);
3779 try {
3780 int testMode = IApplicationThread.DEBUG_OFF;
3781 if (mDebugApp != null && mDebugApp.equals(processName)) {
3782 testMode = mWaitForDebugger
3783 ? IApplicationThread.DEBUG_WAIT
3784 : IApplicationThread.DEBUG_ON;
3785 app.debugging = true;
3786 if (mDebugTransient) {
3787 mDebugApp = mOrigDebugApp;
3788 mWaitForDebugger = mOrigWaitForDebugger;
3789 }
3790 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003791 String profileFile = app.instrumentationProfileFile;
3792 ParcelFileDescriptor profileFd = null;
3793 boolean profileAutoStop = false;
3794 if (mProfileApp != null && mProfileApp.equals(processName)) {
3795 mProfileProc = app;
3796 profileFile = mProfileFile;
3797 profileFd = mProfileFd;
3798 profileAutoStop = mAutoStopProfiler;
3799 }
3800
Christopher Tate181fafa2009-05-14 11:12:14 -07003801 // If the app is being launched for restore or full backup, set it up specially
3802 boolean isRestrictedBackupMode = false;
3803 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3804 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003805 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003806 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3807 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003808
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003809 ensurePackageDexOpt(app.instrumentationInfo != null
3810 ? app.instrumentationInfo.packageName
3811 : app.info.packageName);
3812 if (app.instrumentationClass != null) {
3813 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003814 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003815 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003816 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003817 ApplicationInfo appInfo = app.instrumentationInfo != null
3818 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003819 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003820 if (profileFd != null) {
3821 profileFd = profileFd.dup();
3822 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003823 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003824 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003825 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003826 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08003827 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003828 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003829 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003830 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003831 } catch (Exception e) {
3832 // todo: Yikes! What should we do? For now we will try to
3833 // start another process, but that could easily get us in
3834 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003835 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836
3837 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003838 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003839 startProcessLocked(app, "bind fail", processName);
3840 return false;
3841 }
3842
3843 // Remove this record from the list of starting applications.
3844 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003845 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3846 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003847 mProcessesOnHold.remove(app);
3848
3849 boolean badApp = false;
3850 boolean didSomething = false;
3851
3852 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003853 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003854 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003855 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3856 && processName.equals(hr.processName)) {
3857 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003858 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003859 didSomething = true;
3860 }
3861 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003862 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003863 + hr.intent.getComponent().flattenToShortString(), e);
3864 badApp = true;
3865 }
3866 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003867 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003868 }
3869 }
3870
3871 // Find any services that should be running in this process...
3872 if (!badApp && mPendingServices.size() > 0) {
3873 ServiceRecord sr = null;
3874 try {
3875 for (int i=0; i<mPendingServices.size(); i++) {
3876 sr = mPendingServices.get(i);
3877 if (app.info.uid != sr.appInfo.uid
3878 || !processName.equals(sr.processName)) {
3879 continue;
3880 }
3881
3882 mPendingServices.remove(i);
3883 i--;
3884 realStartServiceLocked(sr, app);
3885 didSomething = true;
3886 }
3887 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003888 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889 + sr.shortName, e);
3890 badApp = true;
3891 }
3892 }
3893
3894 // Check if the next broadcast receiver is in this process...
3895 BroadcastRecord br = mPendingBroadcast;
3896 if (!badApp && br != null && br.curApp == app) {
3897 try {
3898 mPendingBroadcast = null;
3899 processCurBroadcastLocked(br, app);
3900 didSomething = true;
3901 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003902 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003903 + br.curComponent.flattenToShortString(), e);
3904 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003905 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003906 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3907 br.resultExtras, br.resultAbort, true);
3908 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003909 // We need to reset the state if we fails to start the receiver.
3910 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911 }
3912 }
3913
Christopher Tate181fafa2009-05-14 11:12:14 -07003914 // Check whether the next backup agent is in this process...
3915 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003916 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003917 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003918 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003919 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3920 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3921 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003922 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003923 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003924 e.printStackTrace();
3925 }
3926 }
3927
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003928 if (badApp) {
3929 // todo: Also need to kill application to deal with all
3930 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003931 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003932 return false;
3933 }
3934
3935 if (!didSomething) {
3936 updateOomAdjLocked();
3937 }
3938
3939 return true;
3940 }
3941
3942 public final void attachApplication(IApplicationThread thread) {
3943 synchronized (this) {
3944 int callingPid = Binder.getCallingPid();
3945 final long origId = Binder.clearCallingIdentity();
3946 attachApplicationLocked(thread, callingPid);
3947 Binder.restoreCallingIdentity(origId);
3948 }
3949 }
3950
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003951 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003952 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003953 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3954 if (stopProfiling) {
3955 synchronized (this) {
3956 if (mProfileProc == r.app) {
3957 if (mProfileFd != null) {
3958 try {
3959 mProfileFd.close();
3960 } catch (IOException e) {
3961 }
3962 clearProfilerLocked();
3963 }
3964 }
3965 }
3966 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003967 Binder.restoreCallingIdentity(origId);
3968 }
3969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003971 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003972 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003973 mWindowManager.enableScreenAfterBoot();
3974 }
3975
Dianne Hackborn661cd522011-08-22 00:26:20 -07003976 public void showBootMessage(final CharSequence msg, final boolean always) {
3977 mWindowManager.showBootMessage(msg, always);
3978 }
3979
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003980 public void dismissKeyguardOnNextActivity() {
3981 synchronized (this) {
3982 mMainStack.dismissKeyguardOnNextActivityLocked();
3983 }
3984 }
3985
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003986 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003987 IntentFilter pkgFilter = new IntentFilter();
3988 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3989 pkgFilter.addDataScheme("package");
3990 mContext.registerReceiver(new BroadcastReceiver() {
3991 @Override
3992 public void onReceive(Context context, Intent intent) {
3993 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3994 if (pkgs != null) {
3995 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003996 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003997 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003998 setResultCode(Activity.RESULT_OK);
3999 return;
4000 }
4001 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004002 }
4003 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004004 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004005 }, pkgFilter);
4006
4007 synchronized (this) {
4008 // Ensure that any processes we had put on hold are now started
4009 // up.
4010 final int NP = mProcessesOnHold.size();
4011 if (NP > 0) {
4012 ArrayList<ProcessRecord> procs =
4013 new ArrayList<ProcessRecord>(mProcessesOnHold);
4014 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004015 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4016 + procs.get(ip));
4017 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004018 }
4019 }
4020
4021 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004022 // Start looking for apps that are abusing wake locks.
4023 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004024 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004025 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004026 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004027 broadcastIntentLocked(null, null,
4028 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4029 null, null, 0, null, null,
4030 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4031 false, false, MY_PID, Process.SYSTEM_UID);
4032 }
4033 }
4034 }
4035
4036 final void ensureBootCompleted() {
4037 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004038 boolean enableScreen;
4039 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004040 booting = mBooting;
4041 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004042 enableScreen = !mBooted;
4043 mBooted = true;
4044 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004045
4046 if (booting) {
4047 finishBooting();
4048 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004049
4050 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004051 enableScreenAfterBoot();
4052 }
4053 }
4054
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004055 public final void activityPaused(IBinder token) {
4056 final long origId = Binder.clearCallingIdentity();
4057 mMainStack.activityPaused(token, false);
4058 Binder.restoreCallingIdentity(origId);
4059 }
4060
4061 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4062 CharSequence description) {
4063 if (localLOGV) Slog.v(
4064 TAG, "Activity stopped: token=" + token);
4065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004066 // Refuse possible leaked file descriptors
4067 if (icicle != null && icicle.hasFileDescriptors()) {
4068 throw new IllegalArgumentException("File descriptors passed in Bundle");
4069 }
4070
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004071 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004072
4073 final long origId = Binder.clearCallingIdentity();
4074
4075 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004076 r = mMainStack.isInStackLocked(token);
4077 if (r != null) {
4078 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004079 }
4080 }
4081
4082 if (r != null) {
4083 sendPendingThumbnail(r, null, null, null, false);
4084 }
4085
4086 trimApplications();
4087
4088 Binder.restoreCallingIdentity(origId);
4089 }
4090
4091 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004092 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004093 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004094 }
4095
4096 public String getCallingPackage(IBinder token) {
4097 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004098 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004099 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004100 }
4101 }
4102
4103 public ComponentName getCallingActivity(IBinder token) {
4104 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004105 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004106 return r != null ? r.intent.getComponent() : null;
4107 }
4108 }
4109
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004110 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004111 ActivityRecord r = mMainStack.isInStackLocked(token);
4112 if (r == null) {
4113 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004114 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004115 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 }
4117
4118 public ComponentName getActivityClassForToken(IBinder token) {
4119 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004120 ActivityRecord r = mMainStack.isInStackLocked(token);
4121 if (r == null) {
4122 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004123 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004124 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004125 }
4126 }
4127
4128 public String getPackageForToken(IBinder token) {
4129 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004130 ActivityRecord r = mMainStack.isInStackLocked(token);
4131 if (r == null) {
4132 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004133 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004134 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004135 }
4136 }
4137
4138 public IIntentSender getIntentSender(int type,
4139 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004140 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004141 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004142 if (intents != null) {
4143 if (intents.length < 1) {
4144 throw new IllegalArgumentException("Intents array length must be >= 1");
4145 }
4146 for (int i=0; i<intents.length; i++) {
4147 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004148 if (intent != null) {
4149 if (intent.hasFileDescriptors()) {
4150 throw new IllegalArgumentException("File descriptors passed in Intent");
4151 }
4152 if (type == INTENT_SENDER_BROADCAST &&
4153 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4154 throw new IllegalArgumentException(
4155 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4156 }
4157 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004158 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004159 }
4160 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004161 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004162 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004163 }
4164 }
4165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 synchronized(this) {
4167 int callingUid = Binder.getCallingUid();
4168 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004169 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004170 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004171 .getPackageUid(packageName);
4172 if (uid != Binder.getCallingUid()) {
4173 String msg = "Permission Denial: getIntentSender() from pid="
4174 + Binder.getCallingPid()
4175 + ", uid=" + Binder.getCallingUid()
4176 + ", (need uid=" + uid + ")"
4177 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004178 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004179 throw new SecurityException(msg);
4180 }
4181 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004182
4183 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004184 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004186 } catch (RemoteException e) {
4187 throw new SecurityException(e);
4188 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004189 }
4190 }
4191
4192 IIntentSender getIntentSenderLocked(int type,
4193 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004194 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004195 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004196 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004197 activity = mMainStack.isInStackLocked(token);
4198 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004199 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004200 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004201 if (activity.finishing) {
4202 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004203 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004204 }
4205
4206 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4207 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4208 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4209 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4210 |PendingIntent.FLAG_UPDATE_CURRENT);
4211
4212 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4213 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004214 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004215 WeakReference<PendingIntentRecord> ref;
4216 ref = mIntentSenderRecords.get(key);
4217 PendingIntentRecord rec = ref != null ? ref.get() : null;
4218 if (rec != null) {
4219 if (!cancelCurrent) {
4220 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004221 if (rec.key.requestIntent != null) {
4222 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4223 }
4224 if (intents != null) {
4225 intents[intents.length-1] = rec.key.requestIntent;
4226 rec.key.allIntents = intents;
4227 rec.key.allResolvedTypes = resolvedTypes;
4228 } else {
4229 rec.key.allIntents = null;
4230 rec.key.allResolvedTypes = null;
4231 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004232 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004233 return rec;
4234 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004235 rec.canceled = true;
4236 mIntentSenderRecords.remove(key);
4237 }
4238 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004239 return rec;
4240 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004241 rec = new PendingIntentRecord(this, key, callingUid);
4242 mIntentSenderRecords.put(key, rec.ref);
4243 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4244 if (activity.pendingResults == null) {
4245 activity.pendingResults
4246 = new HashSet<WeakReference<PendingIntentRecord>>();
4247 }
4248 activity.pendingResults.add(rec.ref);
4249 }
4250 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004251 }
4252
4253 public void cancelIntentSender(IIntentSender sender) {
4254 if (!(sender instanceof PendingIntentRecord)) {
4255 return;
4256 }
4257 synchronized(this) {
4258 PendingIntentRecord rec = (PendingIntentRecord)sender;
4259 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004260 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004261 .getPackageUid(rec.key.packageName);
4262 if (uid != Binder.getCallingUid()) {
4263 String msg = "Permission Denial: cancelIntentSender() from pid="
4264 + Binder.getCallingPid()
4265 + ", uid=" + Binder.getCallingUid()
4266 + " is not allowed to cancel packges "
4267 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004268 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004269 throw new SecurityException(msg);
4270 }
4271 } catch (RemoteException e) {
4272 throw new SecurityException(e);
4273 }
4274 cancelIntentSenderLocked(rec, true);
4275 }
4276 }
4277
4278 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4279 rec.canceled = true;
4280 mIntentSenderRecords.remove(rec.key);
4281 if (cleanActivity && rec.key.activity != null) {
4282 rec.key.activity.pendingResults.remove(rec.ref);
4283 }
4284 }
4285
4286 public String getPackageForIntentSender(IIntentSender pendingResult) {
4287 if (!(pendingResult instanceof PendingIntentRecord)) {
4288 return null;
4289 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004290 try {
4291 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4292 return res.key.packageName;
4293 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004294 }
4295 return null;
4296 }
4297
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004298 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4299 if (!(pendingResult instanceof PendingIntentRecord)) {
4300 return false;
4301 }
4302 try {
4303 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4304 if (res.key.allIntents == null) {
4305 return false;
4306 }
4307 for (int i=0; i<res.key.allIntents.length; i++) {
4308 Intent intent = res.key.allIntents[i];
4309 if (intent.getPackage() != null && intent.getComponent() != null) {
4310 return false;
4311 }
4312 }
4313 return true;
4314 } catch (ClassCastException e) {
4315 }
4316 return false;
4317 }
4318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004319 public void setProcessLimit(int max) {
4320 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4321 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004322 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004323 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004324 mProcessLimitOverride = max;
4325 }
4326 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004327 }
4328
4329 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004330 synchronized (this) {
4331 return mProcessLimitOverride;
4332 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004333 }
4334
4335 void foregroundTokenDied(ForegroundToken token) {
4336 synchronized (ActivityManagerService.this) {
4337 synchronized (mPidsSelfLocked) {
4338 ForegroundToken cur
4339 = mForegroundProcesses.get(token.pid);
4340 if (cur != token) {
4341 return;
4342 }
4343 mForegroundProcesses.remove(token.pid);
4344 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4345 if (pr == null) {
4346 return;
4347 }
4348 pr.forcingToForeground = null;
4349 pr.foregroundServices = false;
4350 }
4351 updateOomAdjLocked();
4352 }
4353 }
4354
4355 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4356 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4357 "setProcessForeground()");
4358 synchronized(this) {
4359 boolean changed = false;
4360
4361 synchronized (mPidsSelfLocked) {
4362 ProcessRecord pr = mPidsSelfLocked.get(pid);
4363 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004364 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004365 return;
4366 }
4367 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4368 if (oldToken != null) {
4369 oldToken.token.unlinkToDeath(oldToken, 0);
4370 mForegroundProcesses.remove(pid);
4371 pr.forcingToForeground = null;
4372 changed = true;
4373 }
4374 if (isForeground && token != null) {
4375 ForegroundToken newToken = new ForegroundToken() {
4376 public void binderDied() {
4377 foregroundTokenDied(this);
4378 }
4379 };
4380 newToken.pid = pid;
4381 newToken.token = token;
4382 try {
4383 token.linkToDeath(newToken, 0);
4384 mForegroundProcesses.put(pid, newToken);
4385 pr.forcingToForeground = token;
4386 changed = true;
4387 } catch (RemoteException e) {
4388 // If the process died while doing this, we will later
4389 // do the cleanup with the process death link.
4390 }
4391 }
4392 }
4393
4394 if (changed) {
4395 updateOomAdjLocked();
4396 }
4397 }
4398 }
4399
4400 // =========================================================
4401 // PERMISSIONS
4402 // =========================================================
4403
4404 static class PermissionController extends IPermissionController.Stub {
4405 ActivityManagerService mActivityManagerService;
4406 PermissionController(ActivityManagerService activityManagerService) {
4407 mActivityManagerService = activityManagerService;
4408 }
4409
4410 public boolean checkPermission(String permission, int pid, int uid) {
4411 return mActivityManagerService.checkPermission(permission, pid,
4412 uid) == PackageManager.PERMISSION_GRANTED;
4413 }
4414 }
4415
4416 /**
4417 * This can be called with or without the global lock held.
4418 */
4419 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004420 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004421 // We might be performing an operation on behalf of an indirect binder
4422 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4423 // client identity accordingly before proceeding.
4424 Identity tlsIdentity = sCallerIdentity.get();
4425 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004426 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004427 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4428 uid = tlsIdentity.uid;
4429 pid = tlsIdentity.pid;
4430 }
4431
4432 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004433 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004434 return PackageManager.PERMISSION_GRANTED;
4435 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004436 // If there is a uid that owns whatever is being accessed, it has
4437 // blanket access to it regardless of the permissions it requires.
4438 if (owningUid >= 0 && uid == owningUid) {
4439 return PackageManager.PERMISSION_GRANTED;
4440 }
4441 // If the target is not exported, then nobody else can get to it.
4442 if (!exported) {
4443 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004444 return PackageManager.PERMISSION_DENIED;
4445 }
4446 if (permission == null) {
4447 return PackageManager.PERMISSION_GRANTED;
4448 }
4449 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004450 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004451 .checkUidPermission(permission, uid);
4452 } catch (RemoteException e) {
4453 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004454 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004455 }
4456 return PackageManager.PERMISSION_DENIED;
4457 }
4458
4459 /**
4460 * As the only public entry point for permissions checking, this method
4461 * can enforce the semantic that requesting a check on a null global
4462 * permission is automatically denied. (Internally a null permission
4463 * string is used when calling {@link #checkComponentPermission} in cases
4464 * when only uid-based security is needed.)
4465 *
4466 * This can be called with or without the global lock held.
4467 */
4468 public int checkPermission(String permission, int pid, int uid) {
4469 if (permission == null) {
4470 return PackageManager.PERMISSION_DENIED;
4471 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004472 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004473 }
4474
4475 /**
4476 * Binder IPC calls go through the public entry point.
4477 * This can be called with or without the global lock held.
4478 */
4479 int checkCallingPermission(String permission) {
4480 return checkPermission(permission,
4481 Binder.getCallingPid(),
4482 Binder.getCallingUid());
4483 }
4484
4485 /**
4486 * This can be called with or without the global lock held.
4487 */
4488 void enforceCallingPermission(String permission, String func) {
4489 if (checkCallingPermission(permission)
4490 == PackageManager.PERMISSION_GRANTED) {
4491 return;
4492 }
4493
4494 String msg = "Permission Denial: " + func + " from pid="
4495 + Binder.getCallingPid()
4496 + ", uid=" + Binder.getCallingUid()
4497 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004498 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004499 throw new SecurityException(msg);
4500 }
4501
4502 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004503 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4504 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4505 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4506 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4507 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004508 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004509 // Is the component private from the target uid?
4510 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4511
4512 // Acceptable if the there is no read permission needed from the
4513 // target or the target is holding the read permission.
4514 if (!readPerm) {
4515 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004516 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004517 == PackageManager.PERMISSION_GRANTED)) {
4518 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004519 }
4520 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004521
4522 // Acceptable if the there is no write permission needed from the
4523 // target or the target is holding the read permission.
4524 if (!writePerm) {
4525 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004526 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004527 == PackageManager.PERMISSION_GRANTED)) {
4528 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004529 }
4530 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004531
4532 // Acceptable if there is a path permission matching the URI that
4533 // the target holds the permission on.
4534 PathPermission[] pps = pi.pathPermissions;
4535 if (pps != null && (!readPerm || !writePerm)) {
4536 final String path = uri.getPath();
4537 int i = pps.length;
4538 while (i > 0 && (!readPerm || !writePerm)) {
4539 i--;
4540 PathPermission pp = pps[i];
4541 if (!readPerm) {
4542 final String pprperm = pp.getReadPermission();
4543 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4544 + pprperm + " for " + pp.getPath()
4545 + ": match=" + pp.match(path)
4546 + " check=" + pm.checkUidPermission(pprperm, uid));
4547 if (pprperm != null && pp.match(path) &&
4548 (pm.checkUidPermission(pprperm, uid)
4549 == PackageManager.PERMISSION_GRANTED)) {
4550 readPerm = true;
4551 }
4552 }
4553 if (!writePerm) {
4554 final String ppwperm = pp.getWritePermission();
4555 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4556 + ppwperm + " for " + pp.getPath()
4557 + ": match=" + pp.match(path)
4558 + " check=" + pm.checkUidPermission(ppwperm, uid));
4559 if (ppwperm != null && pp.match(path) &&
4560 (pm.checkUidPermission(ppwperm, uid)
4561 == PackageManager.PERMISSION_GRANTED)) {
4562 writePerm = true;
4563 }
4564 }
4565 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004566 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004567 } catch (RemoteException e) {
4568 return false;
4569 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004570
4571 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004572 }
4573
4574 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4575 int modeFlags) {
4576 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004577 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004578 return true;
4579 }
4580 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4581 if (perms == null) return false;
4582 UriPermission perm = perms.get(uri);
4583 if (perm == null) return false;
4584 return (modeFlags&perm.modeFlags) == modeFlags;
4585 }
4586
4587 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4588 // Another redirected-binder-call permissions check as in
4589 // {@link checkComponentPermission}.
4590 Identity tlsIdentity = sCallerIdentity.get();
4591 if (tlsIdentity != null) {
4592 uid = tlsIdentity.uid;
4593 pid = tlsIdentity.pid;
4594 }
4595
4596 // Our own process gets to do everything.
4597 if (pid == MY_PID) {
4598 return PackageManager.PERMISSION_GRANTED;
4599 }
4600 synchronized(this) {
4601 return checkUriPermissionLocked(uri, uid, modeFlags)
4602 ? PackageManager.PERMISSION_GRANTED
4603 : PackageManager.PERMISSION_DENIED;
4604 }
4605 }
4606
Dianne Hackborn39792d22010-08-19 18:01:52 -07004607 /**
4608 * Check if the targetPkg can be granted permission to access uri by
4609 * the callingUid using the given modeFlags. Throws a security exception
4610 * if callingUid is not allowed to do this. Returns the uid of the target
4611 * if the URI permission grant should be performed; returns -1 if it is not
4612 * needed (for example targetPkg already has permission to access the URI).
4613 */
4614 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4615 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004616 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4617 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4618 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004619 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004620 }
4621
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004622 if (targetPkg != null) {
4623 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4624 "Checking grant " + targetPkg + " permission to " + uri);
4625 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004626
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004627 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004628
4629 // If this is not a content: uri, we can't do anything with it.
4630 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004631 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004632 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004633 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 }
4635
4636 String name = uri.getAuthority();
4637 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004638 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004639 if (cpr != null) {
4640 pi = cpr.info;
4641 } else {
4642 try {
4643 pi = pm.resolveContentProvider(name,
4644 PackageManager.GET_URI_PERMISSION_PATTERNS);
4645 } catch (RemoteException ex) {
4646 }
4647 }
4648 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004649 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004650 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004651 }
4652
4653 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004654 if (targetPkg != null) {
4655 try {
4656 targetUid = pm.getPackageUid(targetPkg);
4657 if (targetUid < 0) {
4658 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4659 "Can't grant URI permission no uid for: " + targetPkg);
4660 return -1;
4661 }
4662 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004663 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004665 } else {
4666 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004667 }
4668
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004669 if (targetUid >= 0) {
4670 // First... does the target actually need this permission?
4671 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4672 // No need to grant the target this permission.
4673 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4674 "Target " + targetPkg + " already has full permission to " + uri);
4675 return -1;
4676 }
4677 } else {
4678 // First... there is no target package, so can anyone access it?
4679 boolean allowed = pi.exported;
4680 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4681 if (pi.readPermission != null) {
4682 allowed = false;
4683 }
4684 }
4685 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4686 if (pi.writePermission != null) {
4687 allowed = false;
4688 }
4689 }
4690 if (allowed) {
4691 return -1;
4692 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004693 }
4694
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004695 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004696 if (!pi.grantUriPermissions) {
4697 throw new SecurityException("Provider " + pi.packageName
4698 + "/" + pi.name
4699 + " does not allow granting of Uri permissions (uri "
4700 + uri + ")");
4701 }
4702 if (pi.uriPermissionPatterns != null) {
4703 final int N = pi.uriPermissionPatterns.length;
4704 boolean allowed = false;
4705 for (int i=0; i<N; i++) {
4706 if (pi.uriPermissionPatterns[i] != null
4707 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4708 allowed = true;
4709 break;
4710 }
4711 }
4712 if (!allowed) {
4713 throw new SecurityException("Provider " + pi.packageName
4714 + "/" + pi.name
4715 + " does not allow granting of permission to path of Uri "
4716 + uri);
4717 }
4718 }
4719
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004720 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004721 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004722 if (callingUid != Process.myUid()) {
4723 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4724 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4725 throw new SecurityException("Uid " + callingUid
4726 + " does not have permission to uri " + uri);
4727 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004728 }
4729 }
4730
Dianne Hackborn39792d22010-08-19 18:01:52 -07004731 return targetUid;
4732 }
4733
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004734 public int checkGrantUriPermission(int callingUid, String targetPkg,
4735 Uri uri, int modeFlags) {
4736 synchronized(this) {
4737 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4738 }
4739 }
4740
Dianne Hackborn39792d22010-08-19 18:01:52 -07004741 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4742 Uri uri, int modeFlags, UriPermissionOwner owner) {
4743 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4744 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4745 if (modeFlags == 0) {
4746 return;
4747 }
4748
4749 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004750 // to the uri, and the target doesn't. Let's now give this to
4751 // the target.
4752
Joe Onorato8a9b2202010-02-26 18:56:32 -08004753 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004754 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004756 HashMap<Uri, UriPermission> targetUris
4757 = mGrantedUriPermissions.get(targetUid);
4758 if (targetUris == null) {
4759 targetUris = new HashMap<Uri, UriPermission>();
4760 mGrantedUriPermissions.put(targetUid, targetUris);
4761 }
4762
4763 UriPermission perm = targetUris.get(uri);
4764 if (perm == null) {
4765 perm = new UriPermission(targetUid, uri);
4766 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004767 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004769 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004770 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004771 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004772 } else {
4773 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4774 perm.readOwners.add(owner);
4775 owner.addReadPermission(perm);
4776 }
4777 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4778 perm.writeOwners.add(owner);
4779 owner.addWritePermission(perm);
4780 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004781 }
4782 }
4783
Dianne Hackborn39792d22010-08-19 18:01:52 -07004784 void grantUriPermissionLocked(int callingUid,
4785 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004786 if (targetPkg == null) {
4787 throw new NullPointerException("targetPkg");
4788 }
4789
Dianne Hackborn39792d22010-08-19 18:01:52 -07004790 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4791 if (targetUid < 0) {
4792 return;
4793 }
4794
4795 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4796 }
4797
4798 /**
4799 * Like checkGrantUriPermissionLocked, but takes an Intent.
4800 */
4801 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4802 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004803 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004804 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004805 + " from " + intent + "; flags=0x"
4806 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4807
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004808 if (targetPkg == null) {
4809 throw new NullPointerException("targetPkg");
4810 }
4811
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004812 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004813 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004814 }
4815 Uri data = intent.getData();
4816 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004817 return -1;
4818 }
4819 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4820 intent.getFlags());
4821 }
4822
4823 /**
4824 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4825 */
4826 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4827 String targetPkg, Intent intent, UriPermissionOwner owner) {
4828 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4829 intent.getFlags(), owner);
4830 }
4831
4832 void grantUriPermissionFromIntentLocked(int callingUid,
4833 String targetPkg, Intent intent, UriPermissionOwner owner) {
4834 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4835 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004836 return;
4837 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004838
4839 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004840 }
4841
4842 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4843 Uri uri, int modeFlags) {
4844 synchronized(this) {
4845 final ProcessRecord r = getRecordForAppLocked(caller);
4846 if (r == null) {
4847 throw new SecurityException("Unable to find app for caller "
4848 + caller
4849 + " when granting permission to uri " + uri);
4850 }
4851 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004852 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004853 }
4854 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004855 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004856 }
4857
4858 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4859 null);
4860 }
4861 }
4862
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004863 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004864 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4865 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4866 HashMap<Uri, UriPermission> perms
4867 = mGrantedUriPermissions.get(perm.uid);
4868 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004869 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004870 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004871 perms.remove(perm.uri);
4872 if (perms.size() == 0) {
4873 mGrantedUriPermissions.remove(perm.uid);
4874 }
4875 }
4876 }
4877 }
4878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004879 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4880 int modeFlags) {
4881 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4882 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4883 if (modeFlags == 0) {
4884 return;
4885 }
4886
Joe Onorato8a9b2202010-02-26 18:56:32 -08004887 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004888 "Revoking all granted permissions to " + uri);
4889
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004890 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004891
4892 final String authority = uri.getAuthority();
4893 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004894 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004895 if (cpr != null) {
4896 pi = cpr.info;
4897 } else {
4898 try {
4899 pi = pm.resolveContentProvider(authority,
4900 PackageManager.GET_URI_PERMISSION_PATTERNS);
4901 } catch (RemoteException ex) {
4902 }
4903 }
4904 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004905 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004906 return;
4907 }
4908
4909 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004910 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004911 // Right now, if you are not the original owner of the permission,
4912 // you are not allowed to revoke it.
4913 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4914 throw new SecurityException("Uid " + callingUid
4915 + " does not have permission to uri " + uri);
4916 //}
4917 }
4918
4919 // Go through all of the permissions and remove any that match.
4920 final List<String> SEGMENTS = uri.getPathSegments();
4921 if (SEGMENTS != null) {
4922 final int NS = SEGMENTS.size();
4923 int N = mGrantedUriPermissions.size();
4924 for (int i=0; i<N; i++) {
4925 HashMap<Uri, UriPermission> perms
4926 = mGrantedUriPermissions.valueAt(i);
4927 Iterator<UriPermission> it = perms.values().iterator();
4928 toploop:
4929 while (it.hasNext()) {
4930 UriPermission perm = it.next();
4931 Uri targetUri = perm.uri;
4932 if (!authority.equals(targetUri.getAuthority())) {
4933 continue;
4934 }
4935 List<String> targetSegments = targetUri.getPathSegments();
4936 if (targetSegments == null) {
4937 continue;
4938 }
4939 if (targetSegments.size() < NS) {
4940 continue;
4941 }
4942 for (int j=0; j<NS; j++) {
4943 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4944 continue toploop;
4945 }
4946 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004947 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004948 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004949 perm.clearModes(modeFlags);
4950 if (perm.modeFlags == 0) {
4951 it.remove();
4952 }
4953 }
4954 if (perms.size() == 0) {
4955 mGrantedUriPermissions.remove(
4956 mGrantedUriPermissions.keyAt(i));
4957 N--;
4958 i--;
4959 }
4960 }
4961 }
4962 }
4963
4964 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4965 int modeFlags) {
4966 synchronized(this) {
4967 final ProcessRecord r = getRecordForAppLocked(caller);
4968 if (r == null) {
4969 throw new SecurityException("Unable to find app for caller "
4970 + caller
4971 + " when revoking permission to uri " + uri);
4972 }
4973 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004974 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004975 return;
4976 }
4977
4978 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4979 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4980 if (modeFlags == 0) {
4981 return;
4982 }
4983
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004984 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004985
4986 final String authority = uri.getAuthority();
4987 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004988 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004989 if (cpr != null) {
4990 pi = cpr.info;
4991 } else {
4992 try {
4993 pi = pm.resolveContentProvider(authority,
4994 PackageManager.GET_URI_PERMISSION_PATTERNS);
4995 } catch (RemoteException ex) {
4996 }
4997 }
4998 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004999 Slog.w(TAG, "No content provider found for permission revoke: "
5000 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005001 return;
5002 }
5003
5004 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
5005 }
5006 }
5007
Dianne Hackborn7e269642010-08-25 19:50:20 -07005008 @Override
5009 public IBinder newUriPermissionOwner(String name) {
5010 synchronized(this) {
5011 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5012 return owner.getExternalTokenLocked();
5013 }
5014 }
5015
5016 @Override
5017 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5018 Uri uri, int modeFlags) {
5019 synchronized(this) {
5020 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5021 if (owner == null) {
5022 throw new IllegalArgumentException("Unknown owner: " + token);
5023 }
5024 if (fromUid != Binder.getCallingUid()) {
5025 if (Binder.getCallingUid() != Process.myUid()) {
5026 // Only system code can grant URI permissions on behalf
5027 // of other users.
5028 throw new SecurityException("nice try");
5029 }
5030 }
5031 if (targetPkg == null) {
5032 throw new IllegalArgumentException("null target");
5033 }
5034 if (uri == null) {
5035 throw new IllegalArgumentException("null uri");
5036 }
5037
5038 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5039 }
5040 }
5041
5042 @Override
5043 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5044 synchronized(this) {
5045 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5046 if (owner == null) {
5047 throw new IllegalArgumentException("Unknown owner: " + token);
5048 }
5049
5050 if (uri == null) {
5051 owner.removeUriPermissionsLocked(mode);
5052 } else {
5053 owner.removeUriPermissionLocked(uri, mode);
5054 }
5055 }
5056 }
5057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005058 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5059 synchronized (this) {
5060 ProcessRecord app =
5061 who != null ? getRecordForAppLocked(who) : null;
5062 if (app == null) return;
5063
5064 Message msg = Message.obtain();
5065 msg.what = WAIT_FOR_DEBUGGER_MSG;
5066 msg.obj = app;
5067 msg.arg1 = waiting ? 1 : 0;
5068 mHandler.sendMessage(msg);
5069 }
5070 }
5071
5072 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005073 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5074 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005075 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005076 outInfo.threshold = homeAppMem;
5077 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5078 outInfo.hiddenAppThreshold = hiddenAppMem;
5079 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005080 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005081 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5082 ProcessList.VISIBLE_APP_ADJ);
5083 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5084 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005085 }
5086
5087 // =========================================================
5088 // TASK MANAGEMENT
5089 // =========================================================
5090
5091 public List getTasks(int maxNum, int flags,
5092 IThumbnailReceiver receiver) {
5093 ArrayList list = new ArrayList();
5094
5095 PendingThumbnailsRecord pending = null;
5096 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005097 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005098
5099 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005100 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005101 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5102 + ", receiver=" + receiver);
5103
5104 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5105 != PackageManager.PERMISSION_GRANTED) {
5106 if (receiver != null) {
5107 // If the caller wants to wait for pending thumbnails,
5108 // it ain't gonna get them.
5109 try {
5110 receiver.finished();
5111 } catch (RemoteException ex) {
5112 }
5113 }
5114 String msg = "Permission Denial: getTasks() from pid="
5115 + Binder.getCallingPid()
5116 + ", uid=" + Binder.getCallingUid()
5117 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005118 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005119 throw new SecurityException(msg);
5120 }
5121
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005122 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005123 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005124 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005125 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126 TaskRecord curTask = null;
5127 int numActivities = 0;
5128 int numRunning = 0;
5129 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005130 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005131 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005132 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005133
5134 // Initialize state for next task if needed.
5135 if (top == null ||
5136 (top.state == ActivityState.INITIALIZING
5137 && top.task == r.task)) {
5138 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005139 curTask = r.task;
5140 numActivities = numRunning = 0;
5141 }
5142
5143 // Add 'r' into the current task.
5144 numActivities++;
5145 if (r.app != null && r.app.thread != null) {
5146 numRunning++;
5147 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005148
Joe Onorato8a9b2202010-02-26 18:56:32 -08005149 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005150 TAG, r.intent.getComponent().flattenToShortString()
5151 + ": task=" + r.task);
5152
5153 // If the next one is a different task, generate a new
5154 // TaskInfo entry for what we have.
5155 if (next == null || next.task != curTask) {
5156 ActivityManager.RunningTaskInfo ci
5157 = new ActivityManager.RunningTaskInfo();
5158 ci.id = curTask.taskId;
5159 ci.baseActivity = r.intent.getComponent();
5160 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005161 if (top.thumbHolder != null) {
5162 ci.description = top.thumbHolder.lastDescription;
5163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005164 ci.numActivities = numActivities;
5165 ci.numRunning = numRunning;
5166 //System.out.println(
5167 // "#" + maxNum + ": " + " descr=" + ci.description);
5168 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005169 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005170 TAG, "State=" + top.state + "Idle=" + top.idle
5171 + " app=" + top.app
5172 + " thr=" + (top.app != null ? top.app.thread : null));
5173 if (top.state == ActivityState.RESUMED
5174 || top.state == ActivityState.PAUSING) {
5175 if (top.idle && top.app != null
5176 && top.app.thread != null) {
5177 topRecord = top;
5178 topThumbnail = top.app.thread;
5179 } else {
5180 top.thumbnailNeeded = true;
5181 }
5182 }
5183 if (pending == null) {
5184 pending = new PendingThumbnailsRecord(receiver);
5185 }
5186 pending.pendingRecords.add(top);
5187 }
5188 list.add(ci);
5189 maxNum--;
5190 top = null;
5191 }
5192 }
5193
5194 if (pending != null) {
5195 mPendingThumbnails.add(pending);
5196 }
5197 }
5198
Joe Onorato8a9b2202010-02-26 18:56:32 -08005199 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005200
5201 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005202 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005203 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08005204 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005205 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005206 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005207 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005208 }
5209 }
5210
5211 if (pending == null && receiver != null) {
5212 // In this case all thumbnails were available and the client
5213 // is being asked to be told when the remaining ones come in...
5214 // which is unusually, since the top-most currently running
5215 // activity should never have a canned thumbnail! Oh well.
5216 try {
5217 receiver.finished();
5218 } catch (RemoteException ex) {
5219 }
5220 }
5221
5222 return list;
5223 }
5224
5225 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5226 int flags) {
5227 synchronized (this) {
5228 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5229 "getRecentTasks()");
5230
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005231 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005233 final int N = mRecentTasks.size();
5234 ArrayList<ActivityManager.RecentTaskInfo> res
5235 = new ArrayList<ActivityManager.RecentTaskInfo>(
5236 maxNum < N ? maxNum : N);
5237 for (int i=0; i<N && maxNum > 0; i++) {
5238 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005239 // Return the entry if desired by the caller. We always return
5240 // the first entry, because callers always expect this to be the
5241 // forground app. We may filter others if the caller has
5242 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5243 // we should exclude the entry.
5244 if (i == 0
5245 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005246 || (tr.intent == null)
5247 || ((tr.intent.getFlags()
5248 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5249 ActivityManager.RecentTaskInfo rti
5250 = new ActivityManager.RecentTaskInfo();
5251 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005252 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005253 rti.baseIntent = new Intent(
5254 tr.intent != null ? tr.intent : tr.affinityIntent);
5255 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005256 rti.description = tr.lastDescription;
5257
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005258 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5259 // Check whether this activity is currently available.
5260 try {
5261 if (rti.origActivity != null) {
5262 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5263 continue;
5264 }
5265 } else if (rti.baseIntent != null) {
5266 if (pm.queryIntentActivities(rti.baseIntent,
5267 null, 0) == null) {
5268 continue;
5269 }
5270 }
5271 } catch (RemoteException e) {
5272 // Will never happen.
5273 }
5274 }
5275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005276 res.add(rti);
5277 maxNum--;
5278 }
5279 }
5280 return res;
5281 }
5282 }
5283
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005284 private TaskRecord taskForIdLocked(int id) {
5285 final int N = mRecentTasks.size();
5286 for (int i=0; i<N; i++) {
5287 TaskRecord tr = mRecentTasks.get(i);
5288 if (tr.taskId == id) {
5289 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005290 }
5291 }
5292 return null;
5293 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005294
5295 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5296 synchronized (this) {
5297 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5298 "getTaskThumbnails()");
5299 TaskRecord tr = taskForIdLocked(id);
5300 if (tr != null) {
5301 return mMainStack.getTaskThumbnailsLocked(tr);
5302 }
5303 }
5304 return null;
5305 }
5306
5307 public boolean removeSubTask(int taskId, int subTaskIndex) {
5308 synchronized (this) {
5309 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5310 "removeSubTask()");
5311 long ident = Binder.clearCallingIdentity();
5312 try {
5313 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5314 } finally {
5315 Binder.restoreCallingIdentity(ident);
5316 }
5317 }
5318 }
5319
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005320 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005321 TaskRecord tr = root.task;
5322 Intent baseIntent = new Intent(
5323 tr.intent != null ? tr.intent : tr.affinityIntent);
5324 ComponentName component = baseIntent.getComponent();
5325 if (component == null) {
5326 Slog.w(TAG, "Now component for base intent of task: " + tr);
5327 return;
5328 }
5329
5330 // Find any running services associated with this app.
5331 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5332 for (ServiceRecord sr : mServices.values()) {
5333 if (sr.packageName.equals(component.getPackageName())) {
5334 services.add(sr);
5335 }
5336 }
5337
5338 // Take care of any running services associated with the app.
5339 for (int i=0; i<services.size(); i++) {
5340 ServiceRecord sr = services.get(i);
5341 if (sr.startRequested) {
5342 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005343 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005344 stopServiceLocked(sr);
5345 } else {
5346 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5347 sr.makeNextStartId(), baseIntent, -1));
5348 if (sr.app != null && sr.app.thread != null) {
5349 sendServiceArgsLocked(sr, false);
5350 }
5351 }
5352 }
5353 }
5354
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005355 if (killProcesses) {
5356 // Find any running processes associated with this app.
5357 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5358 SparseArray<ProcessRecord> appProcs
5359 = mProcessNames.getMap().get(component.getPackageName());
5360 if (appProcs != null) {
5361 for (int i=0; i<appProcs.size(); i++) {
5362 procs.add(appProcs.valueAt(i));
5363 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005364 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005365
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005366 // Kill the running processes.
5367 for (int i=0; i<procs.size(); i++) {
5368 ProcessRecord pr = procs.get(i);
5369 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5370 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5371 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5372 pr.processName, pr.setAdj, "remove task");
5373 Process.killProcessQuiet(pr.pid);
5374 } else {
5375 pr.waitingToKill = "remove task";
5376 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005377 }
5378 }
5379 }
5380
5381 public boolean removeTask(int taskId, int flags) {
5382 synchronized (this) {
5383 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5384 "removeTask()");
5385 long ident = Binder.clearCallingIdentity();
5386 try {
5387 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5388 if (r != null) {
5389 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005390 cleanUpRemovedTaskLocked(r,
5391 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005392 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005393 } else {
5394 TaskRecord tr = null;
5395 int i=0;
5396 while (i < mRecentTasks.size()) {
5397 TaskRecord t = mRecentTasks.get(i);
5398 if (t.taskId == taskId) {
5399 tr = t;
5400 break;
5401 }
5402 i++;
5403 }
5404 if (tr != null) {
5405 if (tr.numActivities <= 0) {
5406 // Caller is just removing a recent task that is
5407 // not actively running. That is easy!
5408 mRecentTasks.remove(i);
5409 } else {
5410 Slog.w(TAG, "removeTask: task " + taskId
5411 + " does not have activities to remove, "
5412 + " but numActivities=" + tr.numActivities
5413 + ": " + tr);
5414 }
5415 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005416 }
5417 } finally {
5418 Binder.restoreCallingIdentity(ident);
5419 }
5420 }
5421 return false;
5422 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005424 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5425 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005426 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005427 TaskRecord jt = startTask;
5428
5429 // First look backwards
5430 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005431 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 if (r.task != jt) {
5433 jt = r.task;
5434 if (affinity.equals(jt.affinity)) {
5435 return j;
5436 }
5437 }
5438 }
5439
5440 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005441 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005442 jt = startTask;
5443 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005444 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005445 if (r.task != jt) {
5446 if (affinity.equals(jt.affinity)) {
5447 return j;
5448 }
5449 jt = r.task;
5450 }
5451 }
5452
5453 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005454 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005455 return N-1;
5456 }
5457
5458 return -1;
5459 }
5460
5461 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005462 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005463 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005464 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005465 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5466 "moveTaskToFront()");
5467
5468 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005469 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5470 Binder.getCallingUid(), "Task to front")) {
5471 return;
5472 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005473 final long origId = Binder.clearCallingIdentity();
5474 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005475 TaskRecord tr = taskForIdLocked(task);
5476 if (tr != null) {
5477 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5478 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005479 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005480 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5481 // Caller wants the home activity moved with it. To accomplish this,
5482 // we'll just move the home task to the top first.
5483 mMainStack.moveHomeToFrontLocked();
5484 }
5485 mMainStack.moveTaskToFrontLocked(tr, null);
5486 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005487 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005488 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5489 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005490 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005491 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5492 mMainStack.mUserLeaving = true;
5493 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005494 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5495 // Caller wants the home activity moved with it. To accomplish this,
5496 // we'll just move the home task to the top first.
5497 mMainStack.moveHomeToFrontLocked();
5498 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005499 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005500 return;
5501 }
5502 }
5503 } finally {
5504 Binder.restoreCallingIdentity(origId);
5505 }
5506 }
5507 }
5508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005509 public void moveTaskToBack(int task) {
5510 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5511 "moveTaskToBack()");
5512
5513 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005514 if (mMainStack.mResumedActivity != null
5515 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005516 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5517 Binder.getCallingUid(), "Task to back")) {
5518 return;
5519 }
5520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005521 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005522 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005523 Binder.restoreCallingIdentity(origId);
5524 }
5525 }
5526
5527 /**
5528 * Moves an activity, and all of the other activities within the same task, to the bottom
5529 * of the history stack. The activity's order within the task is unchanged.
5530 *
5531 * @param token A reference to the activity we wish to move
5532 * @param nonRoot If false then this only works if the activity is the root
5533 * of a task; if true it will work for any activity in a task.
5534 * @return Returns true if the move completed, false if not.
5535 */
5536 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5537 synchronized(this) {
5538 final long origId = Binder.clearCallingIdentity();
5539 int taskId = getTaskForActivityLocked(token, !nonRoot);
5540 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005541 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005542 }
5543 Binder.restoreCallingIdentity(origId);
5544 }
5545 return false;
5546 }
5547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005548 public void moveTaskBackwards(int task) {
5549 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5550 "moveTaskBackwards()");
5551
5552 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005553 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5554 Binder.getCallingUid(), "Task backwards")) {
5555 return;
5556 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005557 final long origId = Binder.clearCallingIdentity();
5558 moveTaskBackwardsLocked(task);
5559 Binder.restoreCallingIdentity(origId);
5560 }
5561 }
5562
5563 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005564 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005565 }
5566
5567 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5568 synchronized(this) {
5569 return getTaskForActivityLocked(token, onlyRoot);
5570 }
5571 }
5572
5573 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005574 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005575 TaskRecord lastTask = null;
5576 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005577 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005578 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005579 if (!onlyRoot || lastTask != r.task) {
5580 return r.task.taskId;
5581 }
5582 return -1;
5583 }
5584 lastTask = r.task;
5585 }
5586
5587 return -1;
5588 }
5589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005590 public void finishOtherInstances(IBinder token, ComponentName className) {
5591 synchronized(this) {
5592 final long origId = Binder.clearCallingIdentity();
5593
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005594 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005595 TaskRecord lastTask = null;
5596 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005597 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005598 if (r.realActivity.equals(className)
Dianne Hackbornbe707852011-11-11 14:32:10 -08005599 && r.appToken != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005600 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005601 null, "others")) {
5602 i--;
5603 N--;
5604 }
5605 }
5606 lastTask = r.task;
5607 }
5608
5609 Binder.restoreCallingIdentity(origId);
5610 }
5611 }
5612
5613 // =========================================================
5614 // THUMBNAILS
5615 // =========================================================
5616
5617 public void reportThumbnail(IBinder token,
5618 Bitmap thumbnail, CharSequence description) {
5619 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5620 final long origId = Binder.clearCallingIdentity();
5621 sendPendingThumbnail(null, token, thumbnail, description, true);
5622 Binder.restoreCallingIdentity(origId);
5623 }
5624
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005625 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005626 Bitmap thumbnail, CharSequence description, boolean always) {
5627 TaskRecord task = null;
5628 ArrayList receivers = null;
5629
5630 //System.out.println("Send pending thumbnail: " + r);
5631
5632 synchronized(this) {
5633 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005634 r = mMainStack.isInStackLocked(token);
5635 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005636 return;
5637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005638 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005639 if (thumbnail == null && r.thumbHolder != null) {
5640 thumbnail = r.thumbHolder.lastThumbnail;
5641 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005642 }
5643 if (thumbnail == null && !always) {
5644 // If there is no thumbnail, and this entry is not actually
5645 // going away, then abort for now and pick up the next
5646 // thumbnail we get.
5647 return;
5648 }
5649 task = r.task;
5650
5651 int N = mPendingThumbnails.size();
5652 int i=0;
5653 while (i<N) {
5654 PendingThumbnailsRecord pr =
5655 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5656 //System.out.println("Looking in " + pr.pendingRecords);
5657 if (pr.pendingRecords.remove(r)) {
5658 if (receivers == null) {
5659 receivers = new ArrayList();
5660 }
5661 receivers.add(pr);
5662 if (pr.pendingRecords.size() == 0) {
5663 pr.finished = true;
5664 mPendingThumbnails.remove(i);
5665 N--;
5666 continue;
5667 }
5668 }
5669 i++;
5670 }
5671 }
5672
5673 if (receivers != null) {
5674 final int N = receivers.size();
5675 for (int i=0; i<N; i++) {
5676 try {
5677 PendingThumbnailsRecord pr =
5678 (PendingThumbnailsRecord)receivers.get(i);
5679 pr.receiver.newThumbnail(
5680 task != null ? task.taskId : -1, thumbnail, description);
5681 if (pr.finished) {
5682 pr.receiver.finished();
5683 }
5684 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005685 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005686 }
5687 }
5688 }
5689 }
5690
5691 // =========================================================
5692 // CONTENT PROVIDERS
5693 // =========================================================
5694
Jeff Brown10e89712011-07-08 18:52:57 -07005695 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5696 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005697 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005698 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005699 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005700 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005701 } catch (RemoteException ex) {
5702 }
5703 if (providers != null) {
5704 final int N = providers.size();
5705 for (int i=0; i<N; i++) {
5706 ProviderInfo cpi =
5707 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005708 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5709 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005710 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005711 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005712 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005713 }
5714 app.pubProviders.put(cpi.name, cpr);
5715 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005716 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005717 }
5718 }
5719 return providers;
5720 }
5721
5722 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005723 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005724 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5725 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5726 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005727 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005728 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005729 return null;
5730 }
5731 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005732 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005733 == PackageManager.PERMISSION_GRANTED) {
5734 return null;
5735 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005736
5737 PathPermission[] pps = cpi.pathPermissions;
5738 if (pps != null) {
5739 int i = pps.length;
5740 while (i > 0) {
5741 i--;
5742 PathPermission pp = pps[i];
5743 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005744 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005745 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005746 return null;
5747 }
5748 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005749 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005750 == PackageManager.PERMISSION_GRANTED) {
5751 return null;
5752 }
5753 }
5754 }
5755
Dianne Hackbornb424b632010-08-18 15:59:05 -07005756 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5757 if (perms != null) {
5758 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5759 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5760 return null;
5761 }
5762 }
5763 }
5764
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005765 String msg;
5766 if (!cpi.exported) {
5767 msg = "Permission Denial: opening provider " + cpi.name
5768 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5769 + ", uid=" + callingUid + ") that is not exported from uid "
5770 + cpi.applicationInfo.uid;
5771 } else {
5772 msg = "Permission Denial: opening provider " + cpi.name
5773 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5774 + ", uid=" + callingUid + ") requires "
5775 + cpi.readPermission + " or " + cpi.writePermission;
5776 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005777 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005778 return msg;
5779 }
5780
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005781 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5782 if (r != null) {
5783 Integer cnt = r.conProviders.get(cpr);
5784 if (DEBUG_PROVIDER) Slog.v(TAG,
5785 "Adding provider requested by "
5786 + r.processName + " from process "
5787 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5788 + " cnt=" + (cnt == null ? 1 : cnt));
5789 if (cnt == null) {
5790 cpr.clients.add(r);
5791 r.conProviders.put(cpr, new Integer(1));
5792 return true;
5793 } else {
5794 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5795 }
5796 } else {
5797 cpr.externals++;
5798 }
5799 return false;
5800 }
5801
5802 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5803 if (r != null) {
5804 Integer cnt = r.conProviders.get(cpr);
5805 if (DEBUG_PROVIDER) Slog.v(TAG,
5806 "Removing provider requested by "
5807 + r.processName + " from process "
5808 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5809 + " cnt=" + cnt);
5810 if (cnt == null || cnt.intValue() <= 1) {
5811 cpr.clients.remove(r);
5812 r.conProviders.remove(cpr);
5813 return true;
5814 } else {
5815 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5816 }
5817 } else {
5818 cpr.externals++;
5819 }
5820 return false;
5821 }
5822
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005823 private final ContentProviderHolder getContentProviderImpl(
5824 IApplicationThread caller, String name) {
5825 ContentProviderRecord cpr;
5826 ProviderInfo cpi = null;
5827
5828 synchronized(this) {
5829 ProcessRecord r = null;
5830 if (caller != null) {
5831 r = getRecordForAppLocked(caller);
5832 if (r == null) {
5833 throw new SecurityException(
5834 "Unable to find app for caller " + caller
5835 + " (pid=" + Binder.getCallingPid()
5836 + ") when getting content provider " + name);
5837 }
5838 }
5839
5840 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005841 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005842 boolean providerRunning = cpr != null;
5843 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005844 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005845 String msg;
5846 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5847 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005848 }
5849
5850 if (r != null && cpr.canRunHere(r)) {
5851 // This provider has been published or is in the process
5852 // of being published... but it is also allowed to run
5853 // in the caller's process, so don't make a connection
5854 // and just let the caller instantiate its own instance.
5855 if (cpr.provider != null) {
5856 // don't give caller the provider object, it needs
5857 // to make its own.
5858 cpr = new ContentProviderRecord(cpr);
5859 }
5860 return cpr;
5861 }
5862
5863 final long origId = Binder.clearCallingIdentity();
5864
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005865 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005866 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005867 final boolean countChanged = incProviderCount(r, cpr);
5868 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005869 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005870 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005871 // make sure to count it as being accessed and thus
5872 // back up on the LRU list. This is good because
5873 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005874 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005875 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005876 }
5877
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005878 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005879 if (false) {
5880 if (cpr.name.flattenToShortString().equals(
5881 "com.android.providers.calendar/.CalendarProvider2")) {
5882 Slog.v(TAG, "****************** KILLING "
5883 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005884 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005885 }
5886 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005887 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005888 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5889 // NOTE: there is still a race here where a signal could be
5890 // pending on the process even though we managed to update its
5891 // adj level. Not sure what to do about this, but at least
5892 // the race is now smaller.
5893 if (!success) {
5894 // Uh oh... it looks like the provider's process
5895 // has been killed on us. We need to wait for a new
5896 // process to be started, and make sure its death
5897 // doesn't kill our process.
5898 Slog.i(TAG,
5899 "Existing provider " + cpr.name.flattenToShortString()
5900 + " is crashing; detaching " + r);
5901 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005902 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005903 if (!lastRef) {
5904 // This wasn't the last ref our process had on
5905 // the provider... we have now been killed, bail.
5906 return null;
5907 }
5908 providerRunning = false;
5909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005910 }
5911
5912 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005913 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005914
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005915 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005916 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005917 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005918 resolveContentProvider(name,
5919 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005920 } catch (RemoteException ex) {
5921 }
5922 if (cpi == null) {
5923 return null;
5924 }
5925
Dianne Hackbornb424b632010-08-18 15:59:05 -07005926 String msg;
5927 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5928 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005929 }
5930
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005931 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005932 && !cpi.processName.equals("system")) {
5933 // If this content provider does not run in the system
5934 // process, and the system is not yet ready to run other
5935 // processes, then fail fast instead of hanging.
5936 throw new IllegalArgumentException(
5937 "Attempt to launch content provider before system ready");
5938 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005939
5940 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5941 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005942 final boolean firstClass = cpr == null;
5943 if (firstClass) {
5944 try {
5945 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005946 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005947 getApplicationInfo(
5948 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005949 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005950 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005951 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005952 + cpi.name);
5953 return null;
5954 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005955 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005956 } catch (RemoteException ex) {
5957 // pm is in same process, this will never happen.
5958 }
5959 }
5960
5961 if (r != null && cpr.canRunHere(r)) {
5962 // If this is a multiprocess provider, then just return its
5963 // info and allow the caller to instantiate it. Only do
5964 // this if the provider is the same user as the caller's
5965 // process, or can run as root (so can be in any process).
5966 return cpr;
5967 }
5968
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005969 if (DEBUG_PROVIDER) {
5970 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005971 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005972 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005973 }
5974
5975 // This is single process, and our app is now connecting to it.
5976 // See if we are already in the process of launching this
5977 // provider.
5978 final int N = mLaunchingProviders.size();
5979 int i;
5980 for (i=0; i<N; i++) {
5981 if (mLaunchingProviders.get(i) == cpr) {
5982 break;
5983 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005984 }
5985
5986 // If the provider is not already being launched, then get it
5987 // started.
5988 if (i >= N) {
5989 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005990
5991 try {
5992 // Content provider is now in use, its package can't be stopped.
5993 try {
5994 AppGlobals.getPackageManager().setPackageStoppedState(
5995 cpr.appInfo.packageName, false);
5996 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005997 } catch (IllegalArgumentException e) {
5998 Slog.w(TAG, "Failed trying to unstop package "
5999 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006000 }
6001
6002 ProcessRecord proc = startProcessLocked(cpi.processName,
6003 cpr.appInfo, false, 0, "content provider",
6004 new ComponentName(cpi.applicationInfo.packageName,
6005 cpi.name), false);
6006 if (proc == null) {
6007 Slog.w(TAG, "Unable to launch app "
6008 + cpi.applicationInfo.packageName + "/"
6009 + cpi.applicationInfo.uid + " for provider "
6010 + name + ": process is bad");
6011 return null;
6012 }
6013 cpr.launchingApp = proc;
6014 mLaunchingProviders.add(cpr);
6015 } finally {
6016 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006017 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006018 }
6019
6020 // Make sure the provider is published (the same provider class
6021 // may be published under multiple names).
6022 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006023 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006024 }
6025 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006026 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006027 }
6028 }
6029
6030 // Wait for the provider to be published...
6031 synchronized (cpr) {
6032 while (cpr.provider == null) {
6033 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006034 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006035 + cpi.applicationInfo.packageName + "/"
6036 + cpi.applicationInfo.uid + " for provider "
6037 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006038 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006039 cpi.applicationInfo.packageName,
6040 cpi.applicationInfo.uid, name);
6041 return null;
6042 }
6043 try {
6044 cpr.wait();
6045 } catch (InterruptedException ex) {
6046 }
6047 }
6048 }
6049 return cpr;
6050 }
6051
6052 public final ContentProviderHolder getContentProvider(
6053 IApplicationThread caller, String name) {
6054 if (caller == null) {
6055 String msg = "null IApplicationThread when getting content provider "
6056 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006057 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006058 throw new SecurityException(msg);
6059 }
6060
6061 return getContentProviderImpl(caller, name);
6062 }
6063
6064 private ContentProviderHolder getContentProviderExternal(String name) {
6065 return getContentProviderImpl(null, name);
6066 }
6067
6068 /**
6069 * Drop a content provider from a ProcessRecord's bookkeeping
6070 * @param cpr
6071 */
6072 public void removeContentProvider(IApplicationThread caller, String name) {
6073 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006074 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006075 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006076 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006077 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006078 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006079 return;
6080 }
6081 final ProcessRecord r = getRecordForAppLocked(caller);
6082 if (r == null) {
6083 throw new SecurityException(
6084 "Unable to find app for caller " + caller +
6085 " when removing content provider " + name);
6086 }
6087 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006088 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6089 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006090 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006091 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08006092 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006093 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006094 return;
6095 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006096 if (decProviderCount(r, localCpr)) {
6097 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07006098 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006099 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006100 }
6101 }
6102
6103 private void removeContentProviderExternal(String name) {
6104 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006105 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006106 if(cpr == null) {
6107 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006108 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006109 return;
6110 }
6111
6112 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006113 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6114 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006115 localCpr.externals--;
6116 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006117 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006118 }
6119 updateOomAdjLocked();
6120 }
6121 }
6122
6123 public final void publishContentProviders(IApplicationThread caller,
6124 List<ContentProviderHolder> providers) {
6125 if (providers == null) {
6126 return;
6127 }
6128
6129 synchronized(this) {
6130 final ProcessRecord r = getRecordForAppLocked(caller);
6131 if (r == null) {
6132 throw new SecurityException(
6133 "Unable to find app for caller " + caller
6134 + " (pid=" + Binder.getCallingPid()
6135 + ") when publishing content providers");
6136 }
6137
6138 final long origId = Binder.clearCallingIdentity();
6139
6140 final int N = providers.size();
6141 for (int i=0; i<N; i++) {
6142 ContentProviderHolder src = providers.get(i);
6143 if (src == null || src.info == null || src.provider == null) {
6144 continue;
6145 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006146 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006147 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006148 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6149 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006150 String names[] = dst.info.authority.split(";");
6151 for (int j = 0; j < names.length; j++) {
6152 mProvidersByName.put(names[j], dst);
6153 }
6154
6155 int NL = mLaunchingProviders.size();
6156 int j;
6157 for (j=0; j<NL; j++) {
6158 if (mLaunchingProviders.get(j) == dst) {
6159 mLaunchingProviders.remove(j);
6160 j--;
6161 NL--;
6162 }
6163 }
6164 synchronized (dst) {
6165 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006166 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006167 dst.notifyAll();
6168 }
6169 updateOomAdjLocked(r);
6170 }
6171 }
6172
6173 Binder.restoreCallingIdentity(origId);
6174 }
6175 }
6176
6177 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006178 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006179 synchronized (mSelf) {
6180 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6181 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006182 if (providers != null) {
6183 for (int i=providers.size()-1; i>=0; i--) {
6184 ProviderInfo pi = (ProviderInfo)providers.get(i);
6185 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6186 Slog.w(TAG, "Not installing system proc provider " + pi.name
6187 + ": not system .apk");
6188 providers.remove(i);
6189 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006190 }
6191 }
6192 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006193 if (providers != null) {
6194 mSystemThread.installSystemProviders(providers);
6195 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006196
6197 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006198
6199 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006200 }
6201
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006202 /**
6203 * Allows app to retrieve the MIME type of a URI without having permission
6204 * to access its content provider.
6205 *
6206 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6207 *
6208 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6209 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6210 */
6211 public String getProviderMimeType(Uri uri) {
6212 final String name = uri.getAuthority();
6213 final long ident = Binder.clearCallingIdentity();
6214 ContentProviderHolder holder = null;
6215
6216 try {
6217 holder = getContentProviderExternal(name);
6218 if (holder != null) {
6219 return holder.provider.getType(uri);
6220 }
6221 } catch (RemoteException e) {
6222 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6223 return null;
6224 } finally {
6225 if (holder != null) {
6226 removeContentProviderExternal(name);
6227 }
6228 Binder.restoreCallingIdentity(ident);
6229 }
6230
6231 return null;
6232 }
6233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006234 // =========================================================
6235 // GLOBAL MANAGEMENT
6236 // =========================================================
6237
6238 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6239 ApplicationInfo info, String customProcess) {
6240 String proc = customProcess != null ? customProcess : info.processName;
6241 BatteryStatsImpl.Uid.Proc ps = null;
6242 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6243 synchronized (stats) {
6244 ps = stats.getProcessStatsLocked(info.uid, proc);
6245 }
6246 return new ProcessRecord(ps, thread, info, proc);
6247 }
6248
6249 final ProcessRecord addAppLocked(ApplicationInfo info) {
6250 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6251
6252 if (app == null) {
6253 app = newProcessRecordLocked(null, info, null);
6254 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006255 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006256 }
6257
Dianne Hackborne7f97212011-02-24 14:40:20 -08006258 // This package really, really can not be stopped.
6259 try {
6260 AppGlobals.getPackageManager().setPackageStoppedState(
6261 info.packageName, false);
6262 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006263 } catch (IllegalArgumentException e) {
6264 Slog.w(TAG, "Failed trying to unstop package "
6265 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006266 }
6267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006268 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6269 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6270 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006271 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006272 }
6273 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6274 mPersistentStartingProcesses.add(app);
6275 startProcessLocked(app, "added application", app.processName);
6276 }
6277
6278 return app;
6279 }
6280
6281 public void unhandledBack() {
6282 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6283 "unhandledBack()");
6284
6285 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006286 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006287 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006288 TAG, "Performing unhandledBack(): stack size = " + count);
6289 if (count > 1) {
6290 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006291 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006292 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6293 Binder.restoreCallingIdentity(origId);
6294 }
6295 }
6296 }
6297
6298 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6299 String name = uri.getAuthority();
6300 ContentProviderHolder cph = getContentProviderExternal(name);
6301 ParcelFileDescriptor pfd = null;
6302 if (cph != null) {
6303 // We record the binder invoker's uid in thread-local storage before
6304 // going to the content provider to open the file. Later, in the code
6305 // that handles all permissions checks, we look for this uid and use
6306 // that rather than the Activity Manager's own uid. The effect is that
6307 // we do the check against the caller's permissions even though it looks
6308 // to the content provider like the Activity Manager itself is making
6309 // the request.
6310 sCallerIdentity.set(new Identity(
6311 Binder.getCallingPid(), Binder.getCallingUid()));
6312 try {
6313 pfd = cph.provider.openFile(uri, "r");
6314 } catch (FileNotFoundException e) {
6315 // do nothing; pfd will be returned null
6316 } finally {
6317 // Ensure that whatever happens, we clean up the identity state
6318 sCallerIdentity.remove();
6319 }
6320
6321 // We've got the fd now, so we're done with the provider.
6322 removeContentProviderExternal(name);
6323 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006324 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006325 }
6326 return pfd;
6327 }
6328
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006329 // Actually is sleeping or shutting down or whatever else in the future
6330 // is an inactive state.
6331 public boolean isSleeping() {
6332 return mSleeping || mShuttingDown;
6333 }
6334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006335 public void goingToSleep() {
6336 synchronized(this) {
6337 mSleeping = true;
6338 mWindowManager.setEventDispatching(false);
6339
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006340 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006341
6342 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006343 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006344 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6345 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006346 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006347 }
6348 }
6349
Dianne Hackborn55280a92009-05-07 15:53:46 -07006350 public boolean shutdown(int timeout) {
6351 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6352 != PackageManager.PERMISSION_GRANTED) {
6353 throw new SecurityException("Requires permission "
6354 + android.Manifest.permission.SHUTDOWN);
6355 }
6356
6357 boolean timedout = false;
6358
6359 synchronized(this) {
6360 mShuttingDown = true;
6361 mWindowManager.setEventDispatching(false);
6362
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006363 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006364 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006365 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006366 while (mMainStack.mResumedActivity != null
6367 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006368 long delay = endTime - System.currentTimeMillis();
6369 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006370 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006371 timedout = true;
6372 break;
6373 }
6374 try {
6375 this.wait();
6376 } catch (InterruptedException e) {
6377 }
6378 }
6379 }
6380 }
6381
6382 mUsageStatsService.shutdown();
6383 mBatteryStatsService.shutdown();
6384
6385 return timedout;
6386 }
6387
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006388 public final void activitySlept(IBinder token) {
6389 if (localLOGV) Slog.v(
6390 TAG, "Activity slept: token=" + token);
6391
6392 ActivityRecord r = null;
6393
6394 final long origId = Binder.clearCallingIdentity();
6395
6396 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006397 r = mMainStack.isInStackLocked(token);
6398 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006399 mMainStack.activitySleptLocked(r);
6400 }
6401 }
6402
6403 Binder.restoreCallingIdentity(origId);
6404 }
6405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006406 public void wakingUp() {
6407 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006408 mWindowManager.setEventDispatching(true);
6409 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006410 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006411 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006412 }
6413 }
6414
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006415 public void stopAppSwitches() {
6416 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6417 != PackageManager.PERMISSION_GRANTED) {
6418 throw new SecurityException("Requires permission "
6419 + android.Manifest.permission.STOP_APP_SWITCHES);
6420 }
6421
6422 synchronized(this) {
6423 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6424 + APP_SWITCH_DELAY_TIME;
6425 mDidAppSwitch = false;
6426 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6427 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6428 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6429 }
6430 }
6431
6432 public void resumeAppSwitches() {
6433 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6434 != PackageManager.PERMISSION_GRANTED) {
6435 throw new SecurityException("Requires permission "
6436 + android.Manifest.permission.STOP_APP_SWITCHES);
6437 }
6438
6439 synchronized(this) {
6440 // Note that we don't execute any pending app switches... we will
6441 // let those wait until either the timeout, or the next start
6442 // activity request.
6443 mAppSwitchesAllowedTime = 0;
6444 }
6445 }
6446
6447 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6448 String name) {
6449 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6450 return true;
6451 }
6452
6453 final int perm = checkComponentPermission(
6454 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006455 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006456 if (perm == PackageManager.PERMISSION_GRANTED) {
6457 return true;
6458 }
6459
Joe Onorato8a9b2202010-02-26 18:56:32 -08006460 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006461 return false;
6462 }
6463
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006464 public void setDebugApp(String packageName, boolean waitForDebugger,
6465 boolean persistent) {
6466 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6467 "setDebugApp()");
6468
6469 // Note that this is not really thread safe if there are multiple
6470 // callers into it at the same time, but that's not a situation we
6471 // care about.
6472 if (persistent) {
6473 final ContentResolver resolver = mContext.getContentResolver();
6474 Settings.System.putString(
6475 resolver, Settings.System.DEBUG_APP,
6476 packageName);
6477 Settings.System.putInt(
6478 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6479 waitForDebugger ? 1 : 0);
6480 }
6481
6482 synchronized (this) {
6483 if (!persistent) {
6484 mOrigDebugApp = mDebugApp;
6485 mOrigWaitForDebugger = mWaitForDebugger;
6486 }
6487 mDebugApp = packageName;
6488 mWaitForDebugger = waitForDebugger;
6489 mDebugTransient = !persistent;
6490 if (packageName != null) {
6491 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006492 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006493 Binder.restoreCallingIdentity(origId);
6494 }
6495 }
6496 }
6497
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006498 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6499 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6500 synchronized (this) {
6501 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6502 if (!isDebuggable) {
6503 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6504 throw new SecurityException("Process not debuggable: " + app.packageName);
6505 }
6506 }
6507 mProfileApp = processName;
6508 mProfileFile = profileFile;
6509 if (mProfileFd != null) {
6510 try {
6511 mProfileFd.close();
6512 } catch (IOException e) {
6513 }
6514 mProfileFd = null;
6515 }
6516 mProfileFd = profileFd;
6517 mProfileType = 0;
6518 mAutoStopProfiler = autoStopProfiler;
6519 }
6520 }
6521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006522 public void setAlwaysFinish(boolean enabled) {
6523 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6524 "setAlwaysFinish()");
6525
6526 Settings.System.putInt(
6527 mContext.getContentResolver(),
6528 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6529
6530 synchronized (this) {
6531 mAlwaysFinishActivities = enabled;
6532 }
6533 }
6534
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006535 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006536 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006537 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006538 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006539 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006540 }
6541 }
6542
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006543 public boolean isUserAMonkey() {
6544 // For now the fact that there is a controller implies
6545 // we have a monkey.
6546 synchronized (this) {
6547 return mController != null;
6548 }
6549 }
6550
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006551 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006552 synchronized (this) {
6553 mWatchers.register(watcher);
6554 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006555 }
6556
6557 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006558 synchronized (this) {
6559 mWatchers.unregister(watcher);
6560 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006561 }
6562
Jeff Sharkeya4620792011-05-20 15:29:23 -07006563 public void registerProcessObserver(IProcessObserver observer) {
6564 mProcessObservers.register(observer);
6565 }
6566
6567 public void unregisterProcessObserver(IProcessObserver observer) {
6568 mProcessObservers.unregister(observer);
6569 }
6570
Daniel Sandler69a48172010-06-23 16:29:36 -04006571 public void setImmersive(IBinder token, boolean immersive) {
6572 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006573 ActivityRecord r = mMainStack.isInStackLocked(token);
6574 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006575 throw new IllegalArgumentException();
6576 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006577 r.immersive = immersive;
6578 }
6579 }
6580
6581 public boolean isImmersive(IBinder token) {
6582 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006583 ActivityRecord r = mMainStack.isInStackLocked(token);
6584 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006585 throw new IllegalArgumentException();
6586 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006587 return r.immersive;
6588 }
6589 }
6590
6591 public boolean isTopActivityImmersive() {
6592 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006593 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006594 return (r != null) ? r.immersive : false;
6595 }
6596 }
6597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006598 public final void enterSafeMode() {
6599 synchronized(this) {
6600 // It only makes sense to do this before the system is ready
6601 // and started launching other packages.
6602 if (!mSystemReady) {
6603 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006604 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006605 } catch (RemoteException e) {
6606 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006607 }
6608 }
6609 }
6610
Jeff Brownb09abc12011-01-13 21:08:27 -08006611 public final void showSafeModeOverlay() {
6612 View v = LayoutInflater.from(mContext).inflate(
6613 com.android.internal.R.layout.safe_mode, null);
6614 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6615 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6616 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6617 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6618 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6619 lp.format = v.getBackground().getOpacity();
6620 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6621 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6622 ((WindowManager)mContext.getSystemService(
6623 Context.WINDOW_SERVICE)).addView(v, lp);
6624 }
6625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006626 public void noteWakeupAlarm(IIntentSender sender) {
6627 if (!(sender instanceof PendingIntentRecord)) {
6628 return;
6629 }
6630 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6631 synchronized (stats) {
6632 if (mBatteryStatsService.isOnBattery()) {
6633 mBatteryStatsService.enforceCallingPermission();
6634 PendingIntentRecord rec = (PendingIntentRecord)sender;
6635 int MY_UID = Binder.getCallingUid();
6636 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6637 BatteryStatsImpl.Uid.Pkg pkg =
6638 stats.getPackageStatsLocked(uid, rec.key.packageName);
6639 pkg.incWakeupsLocked();
6640 }
6641 }
6642 }
6643
Dianne Hackborn64825172011-03-02 21:32:58 -08006644 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006645 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006646 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006647 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006648 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006649 // XXX Note: don't acquire main activity lock here, because the window
6650 // manager calls in with its locks held.
6651
6652 boolean killed = false;
6653 synchronized (mPidsSelfLocked) {
6654 int[] types = new int[pids.length];
6655 int worstType = 0;
6656 for (int i=0; i<pids.length; i++) {
6657 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6658 if (proc != null) {
6659 int type = proc.setAdj;
6660 types[i] = type;
6661 if (type > worstType) {
6662 worstType = type;
6663 }
6664 }
6665 }
6666
Dianne Hackborn64825172011-03-02 21:32:58 -08006667 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006668 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006669 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
6670 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07006671 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006672 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006673
6674 // If this is not a secure call, don't let it kill processes that
6675 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006676 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
6677 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006678 }
6679
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006680 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006681 for (int i=0; i<pids.length; i++) {
6682 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6683 if (proc == null) {
6684 continue;
6685 }
6686 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006687 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006688 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006689 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6690 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006691 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006692 proc.killedBackground = true;
6693 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006694 }
6695 }
6696 }
6697 return killed;
6698 }
6699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006700 public final void startRunning(String pkg, String cls, String action,
6701 String data) {
6702 synchronized(this) {
6703 if (mStartRunning) {
6704 return;
6705 }
6706 mStartRunning = true;
6707 mTopComponent = pkg != null && cls != null
6708 ? new ComponentName(pkg, cls) : null;
6709 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6710 mTopData = data;
6711 if (!mSystemReady) {
6712 return;
6713 }
6714 }
6715
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006716 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006717 }
6718
6719 private void retrieveSettings() {
6720 final ContentResolver resolver = mContext.getContentResolver();
6721 String debugApp = Settings.System.getString(
6722 resolver, Settings.System.DEBUG_APP);
6723 boolean waitForDebugger = Settings.System.getInt(
6724 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6725 boolean alwaysFinishActivities = Settings.System.getInt(
6726 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6727
6728 Configuration configuration = new Configuration();
6729 Settings.System.getConfiguration(resolver, configuration);
6730
6731 synchronized (this) {
6732 mDebugApp = mOrigDebugApp = debugApp;
6733 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6734 mAlwaysFinishActivities = alwaysFinishActivities;
6735 // This happens before any activities are started, so we can
6736 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08006737 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006738 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006739 }
6740 }
6741
6742 public boolean testIsSystemReady() {
6743 // no need to synchronize(this) just to read & return the value
6744 return mSystemReady;
6745 }
6746
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006747 private static File getCalledPreBootReceiversFile() {
6748 File dataDir = Environment.getDataDirectory();
6749 File systemDir = new File(dataDir, "system");
6750 File fname = new File(systemDir, "called_pre_boots.dat");
6751 return fname;
6752 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006753
6754 static final int LAST_DONE_VERSION = 10000;
6755
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006756 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6757 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6758 File file = getCalledPreBootReceiversFile();
6759 FileInputStream fis = null;
6760 try {
6761 fis = new FileInputStream(file);
6762 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006763 int fvers = dis.readInt();
6764 if (fvers == LAST_DONE_VERSION) {
6765 String vers = dis.readUTF();
6766 String codename = dis.readUTF();
6767 String build = dis.readUTF();
6768 if (android.os.Build.VERSION.RELEASE.equals(vers)
6769 && android.os.Build.VERSION.CODENAME.equals(codename)
6770 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6771 int num = dis.readInt();
6772 while (num > 0) {
6773 num--;
6774 String pkg = dis.readUTF();
6775 String cls = dis.readUTF();
6776 lastDoneReceivers.add(new ComponentName(pkg, cls));
6777 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006778 }
6779 }
6780 } catch (FileNotFoundException e) {
6781 } catch (IOException e) {
6782 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6783 } finally {
6784 if (fis != null) {
6785 try {
6786 fis.close();
6787 } catch (IOException e) {
6788 }
6789 }
6790 }
6791 return lastDoneReceivers;
6792 }
6793
6794 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6795 File file = getCalledPreBootReceiversFile();
6796 FileOutputStream fos = null;
6797 DataOutputStream dos = null;
6798 try {
6799 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6800 fos = new FileOutputStream(file);
6801 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006802 dos.writeInt(LAST_DONE_VERSION);
6803 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006804 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006805 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006806 dos.writeInt(list.size());
6807 for (int i=0; i<list.size(); i++) {
6808 dos.writeUTF(list.get(i).getPackageName());
6809 dos.writeUTF(list.get(i).getClassName());
6810 }
6811 } catch (IOException e) {
6812 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6813 file.delete();
6814 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006815 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006816 if (dos != null) {
6817 try {
6818 dos.close();
6819 } catch (IOException e) {
6820 // TODO Auto-generated catch block
6821 e.printStackTrace();
6822 }
6823 }
6824 }
6825 }
6826
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006827 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006828 synchronized(this) {
6829 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006830 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006831 return;
6832 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006833
6834 // Check to see if there are any update receivers to run.
6835 if (!mDidUpdate) {
6836 if (mWaitingUpdate) {
6837 return;
6838 }
6839 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6840 List<ResolveInfo> ris = null;
6841 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006842 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006843 intent, null, 0);
6844 } catch (RemoteException e) {
6845 }
6846 if (ris != null) {
6847 for (int i=ris.size()-1; i>=0; i--) {
6848 if ((ris.get(i).activityInfo.applicationInfo.flags
6849 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6850 ris.remove(i);
6851 }
6852 }
6853 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006854
6855 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6856
6857 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006858 for (int i=0; i<ris.size(); i++) {
6859 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006860 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6861 if (lastDoneReceivers.contains(comp)) {
6862 ris.remove(i);
6863 i--;
6864 }
6865 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006866
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006867 for (int i=0; i<ris.size(); i++) {
6868 ActivityInfo ai = ris.get(i).activityInfo;
6869 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6870 doneReceivers.add(comp);
6871 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006872 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006873 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006874 finisher = new IIntentReceiver.Stub() {
6875 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006876 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006877 boolean sticky) {
6878 // The raw IIntentReceiver interface is called
6879 // with the AM lock held, so redispatch to
6880 // execute our code without the lock.
6881 mHandler.post(new Runnable() {
6882 public void run() {
6883 synchronized (ActivityManagerService.this) {
6884 mDidUpdate = true;
6885 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006886 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006887 showBootMessage(mContext.getText(
6888 R.string.android_upgrading_complete),
6889 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006890 systemReady(goingCallback);
6891 }
6892 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006893 }
6894 };
6895 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006896 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006897 broadcastIntentLocked(null, null, intent, null, finisher,
6898 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006899 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006900 mWaitingUpdate = true;
6901 }
6902 }
6903 }
6904 if (mWaitingUpdate) {
6905 return;
6906 }
6907 mDidUpdate = true;
6908 }
6909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006910 mSystemReady = true;
6911 if (!mStartRunning) {
6912 return;
6913 }
6914 }
6915
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006916 ArrayList<ProcessRecord> procsToKill = null;
6917 synchronized(mPidsSelfLocked) {
6918 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6919 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6920 if (!isAllowedWhileBooting(proc.info)){
6921 if (procsToKill == null) {
6922 procsToKill = new ArrayList<ProcessRecord>();
6923 }
6924 procsToKill.add(proc);
6925 }
6926 }
6927 }
6928
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006929 synchronized(this) {
6930 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006931 for (int i=procsToKill.size()-1; i>=0; i--) {
6932 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006933 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08006934 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006935 }
6936 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006937
6938 // Now that we have cleaned up any update processes, we
6939 // are ready to start launching real processes and know that
6940 // we won't trample on them any more.
6941 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006942 }
6943
Joe Onorato8a9b2202010-02-26 18:56:32 -08006944 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006945 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006946 SystemClock.uptimeMillis());
6947
6948 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006949 // Make sure we have no pre-ready processes sitting around.
6950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006951 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6952 ResolveInfo ri = mContext.getPackageManager()
6953 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006954 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006955 CharSequence errorMsg = null;
6956 if (ri != null) {
6957 ActivityInfo ai = ri.activityInfo;
6958 ApplicationInfo app = ai.applicationInfo;
6959 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6960 mTopAction = Intent.ACTION_FACTORY_TEST;
6961 mTopData = null;
6962 mTopComponent = new ComponentName(app.packageName,
6963 ai.name);
6964 } else {
6965 errorMsg = mContext.getResources().getText(
6966 com.android.internal.R.string.factorytest_not_system);
6967 }
6968 } else {
6969 errorMsg = mContext.getResources().getText(
6970 com.android.internal.R.string.factorytest_no_action);
6971 }
6972 if (errorMsg != null) {
6973 mTopAction = null;
6974 mTopData = null;
6975 mTopComponent = null;
6976 Message msg = Message.obtain();
6977 msg.what = SHOW_FACTORY_ERROR_MSG;
6978 msg.getData().putCharSequence("msg", errorMsg);
6979 mHandler.sendMessage(msg);
6980 }
6981 }
6982 }
6983
6984 retrieveSettings();
6985
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006986 if (goingCallback != null) goingCallback.run();
6987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006988 synchronized (this) {
6989 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6990 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006991 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006992 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006993 if (apps != null) {
6994 int N = apps.size();
6995 int i;
6996 for (i=0; i<N; i++) {
6997 ApplicationInfo info
6998 = (ApplicationInfo)apps.get(i);
6999 if (info != null &&
7000 !info.packageName.equals("android")) {
7001 addAppLocked(info);
7002 }
7003 }
7004 }
7005 } catch (RemoteException ex) {
7006 // pm is in same process, this will never happen.
7007 }
7008 }
7009
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007010 // Start up initial activity.
7011 mBooting = true;
7012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007013 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007014 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007015 Message msg = Message.obtain();
7016 msg.what = SHOW_UID_ERROR_MSG;
7017 mHandler.sendMessage(msg);
7018 }
7019 } catch (RemoteException e) {
7020 }
7021
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007022 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007023 }
7024 }
7025
Dan Egnorb7f03672009-12-09 16:22:32 -08007026 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007027 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007028 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007029 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007030 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007031 startAppProblemLocked(app);
7032 app.stopFreezingAllLocked();
7033 return handleAppCrashLocked(app);
7034 }
7035
Dan Egnorb7f03672009-12-09 16:22:32 -08007036 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007037 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007038 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007039 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007040 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7041 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007042 startAppProblemLocked(app);
7043 app.stopFreezingAllLocked();
7044 }
7045
7046 /**
7047 * Generate a process error record, suitable for attachment to a ProcessRecord.
7048 *
7049 * @param app The ProcessRecord in which the error occurred.
7050 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7051 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007052 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007053 * @param shortMsg Short message describing the crash.
7054 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007055 * @param stackTrace Full crash stack trace, may be null.
7056 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007057 * @return Returns a fully-formed AppErrorStateInfo record.
7058 */
7059 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007060 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007061 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007063 report.condition = condition;
7064 report.processName = app.processName;
7065 report.pid = app.pid;
7066 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007067 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007068 report.shortMsg = shortMsg;
7069 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08007070 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007071
7072 return report;
7073 }
7074
Dan Egnor42471dd2010-01-07 17:25:22 -08007075 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007076 synchronized (this) {
7077 app.crashing = false;
7078 app.crashingReport = null;
7079 app.notResponding = false;
7080 app.notRespondingReport = null;
7081 if (app.anrDialog == fromDialog) {
7082 app.anrDialog = null;
7083 }
7084 if (app.waitDialog == fromDialog) {
7085 app.waitDialog = null;
7086 }
7087 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08007088 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007089 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07007090 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7091 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007092 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007093 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007094 }
7095 }
Dan Egnor42471dd2010-01-07 17:25:22 -08007096
Dan Egnorb7f03672009-12-09 16:22:32 -08007097 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007098 long now = SystemClock.uptimeMillis();
7099
7100 Long crashTime = mProcessCrashTimes.get(app.info.processName,
7101 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07007102 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007103 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08007104 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007105 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007106 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007107 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007108 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7109 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007110 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007111 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007112 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007113 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007114 }
7115 }
7116 if (!app.persistent) {
7117 // We don't want to start this process again until the user
7118 // explicitly does so... but for persistent process, we really
7119 // need to keep it running. If a persistent process is actually
7120 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08007121 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007122 app.info.processName);
7123 mBadProcesses.put(app.info.processName, app.info.uid, now);
7124 app.bad = true;
7125 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
7126 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07007127 // Don't let services in this process be restarted and potentially
7128 // annoy the user repeatedly. Unless it is persistent, since those
7129 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007130 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08007131 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007132 return false;
7133 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08007134 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007135 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007136 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007137 if (r.app == app) {
7138 // If the top running activity is from this crashing
7139 // process, then terminate it to avoid getting in a loop.
7140 Slog.w(TAG, " Force finishing activity "
7141 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08007142 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007143 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007144 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08007145 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007146 // stopped, to avoid a situation where one will get
7147 // re-start our crashing activity once it gets resumed again.
7148 index--;
7149 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007150 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007151 if (r.state == ActivityState.RESUMED
7152 || r.state == ActivityState.PAUSING
7153 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007154 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007155 Slog.w(TAG, " Force finishing activity "
7156 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007157 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007158 Activity.RESULT_CANCELED, null, "crashed");
7159 }
7160 }
7161 }
7162 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007163 }
7164
7165 // Bump up the crash count of any services currently running in the proc.
7166 if (app.services.size() != 0) {
7167 // Any services running in the application need to be placed
7168 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007169 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007170 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007171 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007172 sr.crashCount++;
7173 }
7174 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007175
7176 // If the crashing process is what we consider to be the "home process" and it has been
7177 // replaced by a third-party app, clear the package preferred activities from packages
7178 // with a home activity running in the process to prevent a repeatedly crashing app
7179 // from blocking the user to manually clear the list.
7180 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7181 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7182 Iterator it = mHomeProcess.activities.iterator();
7183 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007184 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007185 if (r.isHomeActivity) {
7186 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7187 try {
7188 ActivityThread.getPackageManager()
7189 .clearPackagePreferredActivities(r.packageName);
7190 } catch (RemoteException c) {
7191 // pm is in same process, this will never happen.
7192 }
7193 }
7194 }
7195 }
7196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007197 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7198 return true;
7199 }
7200
7201 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007202 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7203 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007204 skipCurrentReceiverLocked(app);
7205 }
7206
7207 void skipCurrentReceiverLocked(ProcessRecord app) {
7208 boolean reschedule = false;
7209 BroadcastRecord r = app.curReceiver;
7210 if (r != null) {
7211 // The current broadcast is waiting for this app's receiver
7212 // to be finished. Looks like that's not going to happen, so
7213 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007214 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007215 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7216 r.resultExtras, r.resultAbort, true);
7217 reschedule = true;
7218 }
7219 r = mPendingBroadcast;
7220 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007221 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007222 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007223 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007224 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7225 r.resultExtras, r.resultAbort, true);
7226 reschedule = true;
7227 }
7228 if (reschedule) {
7229 scheduleBroadcastsLocked();
7230 }
7231 }
7232
Dan Egnor60d87622009-12-16 16:32:58 -08007233 /**
7234 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7235 * The application process will exit immediately after this call returns.
7236 * @param app object of the crashing app, null for the system server
7237 * @param crashInfo describing the exception
7238 */
7239 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007240 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007241 final String processName = app == null ? "system_server"
7242 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007243
7244 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007245 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007246 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007247 crashInfo.exceptionClassName,
7248 crashInfo.exceptionMessage,
7249 crashInfo.throwFileName,
7250 crashInfo.throwLineNumber);
7251
Jeff Sharkeya353d262011-10-28 11:12:06 -07007252 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007253
7254 crashApplication(r, crashInfo);
7255 }
7256
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007257 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007258 IBinder app,
7259 int violationMask,
7260 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007261 ProcessRecord r = findAppProcess(app, "StrictMode");
7262 if (r == null) {
7263 return;
7264 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007265
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007266 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007267 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007268 boolean logIt = true;
7269 synchronized (mAlreadyLoggedViolatedStacks) {
7270 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7271 logIt = false;
7272 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007273 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007274 // the relative pain numbers, without logging all
7275 // the stack traces repeatedly. We'd want to do
7276 // likewise in the client code, which also does
7277 // dup suppression, before the Binder call.
7278 } else {
7279 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7280 mAlreadyLoggedViolatedStacks.clear();
7281 }
7282 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7283 }
7284 }
7285 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007286 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007287 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007288 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007289
7290 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7291 AppErrorResult result = new AppErrorResult();
7292 synchronized (this) {
7293 final long origId = Binder.clearCallingIdentity();
7294
7295 Message msg = Message.obtain();
7296 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7297 HashMap<String, Object> data = new HashMap<String, Object>();
7298 data.put("result", result);
7299 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007300 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007301 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007302 msg.obj = data;
7303 mHandler.sendMessage(msg);
7304
7305 Binder.restoreCallingIdentity(origId);
7306 }
7307 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007308 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007309 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007310 }
7311
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007312 // Depending on the policy in effect, there could be a bunch of
7313 // these in quick succession so we try to batch these together to
7314 // minimize disk writes, number of dropbox entries, and maximize
7315 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007316 private void logStrictModeViolationToDropBox(
7317 ProcessRecord process,
7318 StrictMode.ViolationInfo info) {
7319 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007320 return;
7321 }
7322 final boolean isSystemApp = process == null ||
7323 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7324 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007325 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007326 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7327 final DropBoxManager dbox = (DropBoxManager)
7328 mContext.getSystemService(Context.DROPBOX_SERVICE);
7329
7330 // Exit early if the dropbox isn't configured to accept this report type.
7331 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7332
7333 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007334 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007335 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7336 synchronized (sb) {
7337 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007338 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007339 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7340 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007341 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7342 if (info.violationNumThisLoop != 0) {
7343 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7344 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007345 if (info.numAnimationsRunning != 0) {
7346 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7347 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007348 if (info.broadcastIntentAction != null) {
7349 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7350 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007351 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007352 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007353 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007354 if (info.numInstances != -1) {
7355 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7356 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007357 if (info.tags != null) {
7358 for (String tag : info.tags) {
7359 sb.append("Span-Tag: ").append(tag).append("\n");
7360 }
7361 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007362 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007363 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7364 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007365 }
7366 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007367
7368 // Only buffer up to ~64k. Various logging bits truncate
7369 // things at 128k.
7370 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007371 }
7372
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007373 // Flush immediately if the buffer's grown too large, or this
7374 // is a non-system app. Non-system apps are isolated with a
7375 // different tag & policy and not batched.
7376 //
7377 // Batching is useful during internal testing with
7378 // StrictMode settings turned up high. Without batching,
7379 // thousands of separate files could be created on boot.
7380 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007381 new Thread("Error dump: " + dropboxTag) {
7382 @Override
7383 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007384 String report;
7385 synchronized (sb) {
7386 report = sb.toString();
7387 sb.delete(0, sb.length());
7388 sb.trimToSize();
7389 }
7390 if (report.length() != 0) {
7391 dbox.addText(dropboxTag, report);
7392 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007393 }
7394 }.start();
7395 return;
7396 }
7397
7398 // System app batching:
7399 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007400 // An existing dropbox-writing thread is outstanding, so
7401 // we don't need to start it up. The existing thread will
7402 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007403 return;
7404 }
7405
7406 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7407 // (After this point, we shouldn't access AMS internal data structures.)
7408 new Thread("Error dump: " + dropboxTag) {
7409 @Override
7410 public void run() {
7411 // 5 second sleep to let stacks arrive and be batched together
7412 try {
7413 Thread.sleep(5000); // 5 seconds
7414 } catch (InterruptedException e) {}
7415
7416 String errorReport;
7417 synchronized (mStrictModeBuffer) {
7418 errorReport = mStrictModeBuffer.toString();
7419 if (errorReport.length() == 0) {
7420 return;
7421 }
7422 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7423 mStrictModeBuffer.trimToSize();
7424 }
7425 dbox.addText(dropboxTag, errorReport);
7426 }
7427 }.start();
7428 }
7429
Dan Egnor60d87622009-12-16 16:32:58 -08007430 /**
7431 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7432 * @param app object of the crashing app, null for the system server
7433 * @param tag reported by the caller
7434 * @param crashInfo describing the context of the error
7435 * @return true if the process should exit immediately (WTF is fatal)
7436 */
7437 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007438 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007439 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007440 final String processName = app == null ? "system_server"
7441 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007442
7443 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007444 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007445 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007446 tag, crashInfo.exceptionMessage);
7447
Jeff Sharkeya353d262011-10-28 11:12:06 -07007448 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007449
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007450 if (r != null && r.pid != Process.myPid() &&
7451 Settings.Secure.getInt(mContext.getContentResolver(),
7452 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007453 crashApplication(r, crashInfo);
7454 return true;
7455 } else {
7456 return false;
7457 }
7458 }
7459
7460 /**
7461 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7462 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7463 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007464 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007465 if (app == null) {
7466 return null;
7467 }
7468
7469 synchronized (this) {
7470 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7471 final int NA = apps.size();
7472 for (int ia=0; ia<NA; ia++) {
7473 ProcessRecord p = apps.valueAt(ia);
7474 if (p.thread != null && p.thread.asBinder() == app) {
7475 return p;
7476 }
7477 }
7478 }
7479
Dianne Hackborncb44d962011-03-10 17:02:27 -08007480 Slog.w(TAG, "Can't find mystery application for " + reason
7481 + " from pid=" + Binder.getCallingPid()
7482 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007483 return null;
7484 }
7485 }
7486
7487 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007488 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7489 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007490 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07007491 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7492 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007493 // Watchdog thread ends up invoking this function (with
7494 // a null ProcessRecord) to add the stack file to dropbox.
7495 // Do not acquire a lock on this (am) in such cases, as it
7496 // could cause a potential deadlock, if and when watchdog
7497 // is invoked due to unavailability of lock on am and it
7498 // would prevent watchdog from killing system_server.
7499 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007500 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007501 return;
7502 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007503 // Note: ProcessRecord 'process' is guarded by the service
7504 // instance. (notably process.pkgList, which could otherwise change
7505 // concurrently during execution of this method)
7506 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007507 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08007508 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007509 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007510 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7511 for (String pkg : process.pkgList) {
7512 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007513 try {
Dan Egnora455d192010-03-12 08:52:28 -08007514 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7515 if (pi != null) {
7516 sb.append(" v").append(pi.versionCode);
7517 if (pi.versionName != null) {
7518 sb.append(" (").append(pi.versionName).append(")");
7519 }
7520 }
7521 } catch (RemoteException e) {
7522 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007523 }
Dan Egnora455d192010-03-12 08:52:28 -08007524 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007525 }
Dan Egnora455d192010-03-12 08:52:28 -08007526 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007527 }
7528
7529 private static String processClass(ProcessRecord process) {
7530 if (process == null || process.pid == MY_PID) {
7531 return "system_server";
7532 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7533 return "system_app";
7534 } else {
7535 return "data_app";
7536 }
7537 }
7538
7539 /**
7540 * Write a description of an error (crash, WTF, ANR) to the drop box.
7541 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7542 * @param process which caused the error, null means the system server
7543 * @param activity which triggered the error, null if unknown
7544 * @param parent activity related to the error, null if unknown
7545 * @param subject line related to the error, null if absent
7546 * @param report in long form describing the error, null if absent
7547 * @param logFile to include in the report, null if none
7548 * @param crashInfo giving an application stack trace, null if absent
7549 */
7550 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07007551 ProcessRecord process, String processName, ActivityRecord activity,
7552 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007553 final String report, final File logFile,
7554 final ApplicationErrorReport.CrashInfo crashInfo) {
7555 // NOTE -- this must never acquire the ActivityManagerService lock,
7556 // otherwise the watchdog may be prevented from resetting the system.
7557
7558 final String dropboxTag = processClass(process) + "_" + eventType;
7559 final DropBoxManager dbox = (DropBoxManager)
7560 mContext.getSystemService(Context.DROPBOX_SERVICE);
7561
7562 // Exit early if the dropbox isn't configured to accept this report type.
7563 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7564
7565 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07007566 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007567 if (activity != null) {
7568 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7569 }
7570 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7571 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7572 }
7573 if (parent != null && parent != activity) {
7574 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7575 }
7576 if (subject != null) {
7577 sb.append("Subject: ").append(subject).append("\n");
7578 }
7579 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007580 if (Debug.isDebuggerConnected()) {
7581 sb.append("Debugger: Connected\n");
7582 }
Dan Egnora455d192010-03-12 08:52:28 -08007583 sb.append("\n");
7584
7585 // Do the rest in a worker thread to avoid blocking the caller on I/O
7586 // (After this point, we shouldn't access AMS internal data structures.)
7587 Thread worker = new Thread("Error dump: " + dropboxTag) {
7588 @Override
7589 public void run() {
7590 if (report != null) {
7591 sb.append(report);
7592 }
7593 if (logFile != null) {
7594 try {
7595 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7596 } catch (IOException e) {
7597 Slog.e(TAG, "Error reading " + logFile, e);
7598 }
7599 }
7600 if (crashInfo != null && crashInfo.stackTrace != null) {
7601 sb.append(crashInfo.stackTrace);
7602 }
7603
7604 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7605 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7606 if (lines > 0) {
7607 sb.append("\n");
7608
7609 // Merge several logcat streams, and take the last N lines
7610 InputStreamReader input = null;
7611 try {
7612 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7613 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7614 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7615
7616 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7617 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7618 input = new InputStreamReader(logcat.getInputStream());
7619
7620 int num;
7621 char[] buf = new char[8192];
7622 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7623 } catch (IOException e) {
7624 Slog.e(TAG, "Error running logcat", e);
7625 } finally {
7626 if (input != null) try { input.close(); } catch (IOException e) {}
7627 }
7628 }
7629
7630 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007631 }
Dan Egnora455d192010-03-12 08:52:28 -08007632 };
7633
7634 if (process == null || process.pid == MY_PID) {
7635 worker.run(); // We may be about to die -- need to run this synchronously
7636 } else {
7637 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007638 }
7639 }
7640
7641 /**
7642 * Bring up the "unexpected error" dialog box for a crashing app.
7643 * Deal with edge cases (intercepts from instrumented applications,
7644 * ActivityController, error intent receivers, that sort of thing).
7645 * @param r the application crashing
7646 * @param crashInfo describing the failure
7647 */
7648 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007649 long timeMillis = System.currentTimeMillis();
7650 String shortMsg = crashInfo.exceptionClassName;
7651 String longMsg = crashInfo.exceptionMessage;
7652 String stackTrace = crashInfo.stackTrace;
7653 if (shortMsg != null && longMsg != null) {
7654 longMsg = shortMsg + ": " + longMsg;
7655 } else if (shortMsg != null) {
7656 longMsg = shortMsg;
7657 }
7658
Dan Egnor60d87622009-12-16 16:32:58 -08007659 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007660 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007661 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007662 try {
7663 String name = r != null ? r.processName : null;
7664 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007665 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007666 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007667 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007668 + " at watcher's request");
7669 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007670 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007671 }
7672 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007673 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007674 }
7675 }
7676
7677 final long origId = Binder.clearCallingIdentity();
7678
7679 // If this process is running instrumentation, finish it.
7680 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007681 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007682 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007683 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7684 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007685 Bundle info = new Bundle();
7686 info.putString("shortMsg", shortMsg);
7687 info.putString("longMsg", longMsg);
7688 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7689 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007690 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007691 }
7692
Dan Egnor60d87622009-12-16 16:32:58 -08007693 // If we can't identify the process or it's already exceeded its crash quota,
7694 // quit right away without showing a crash dialog.
7695 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007696 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007697 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007698 }
7699
7700 Message msg = Message.obtain();
7701 msg.what = SHOW_ERROR_MSG;
7702 HashMap data = new HashMap();
7703 data.put("result", result);
7704 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007705 msg.obj = data;
7706 mHandler.sendMessage(msg);
7707
7708 Binder.restoreCallingIdentity(origId);
7709 }
7710
7711 int res = result.get();
7712
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007713 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007714 synchronized (this) {
7715 if (r != null) {
7716 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7717 SystemClock.uptimeMillis());
7718 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007719 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007720 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007721 }
7722 }
7723
7724 if (appErrorIntent != null) {
7725 try {
7726 mContext.startActivity(appErrorIntent);
7727 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007728 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007729 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007730 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007731 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007732
7733 Intent createAppErrorIntentLocked(ProcessRecord r,
7734 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7735 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007736 if (report == null) {
7737 return null;
7738 }
7739 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7740 result.setComponent(r.errorReportReceiver);
7741 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7742 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7743 return result;
7744 }
7745
Dan Egnorb7f03672009-12-09 16:22:32 -08007746 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7747 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007748 if (r.errorReportReceiver == null) {
7749 return null;
7750 }
7751
7752 if (!r.crashing && !r.notResponding) {
7753 return null;
7754 }
7755
Dan Egnorb7f03672009-12-09 16:22:32 -08007756 ApplicationErrorReport report = new ApplicationErrorReport();
7757 report.packageName = r.info.packageName;
7758 report.installerPackageName = r.errorReportReceiver.getPackageName();
7759 report.processName = r.processName;
7760 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007761 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007762
Dan Egnorb7f03672009-12-09 16:22:32 -08007763 if (r.crashing) {
7764 report.type = ApplicationErrorReport.TYPE_CRASH;
7765 report.crashInfo = crashInfo;
7766 } else if (r.notResponding) {
7767 report.type = ApplicationErrorReport.TYPE_ANR;
7768 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007769
Dan Egnorb7f03672009-12-09 16:22:32 -08007770 report.anrInfo.activity = r.notRespondingReport.tag;
7771 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7772 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007773 }
7774
Dan Egnorb7f03672009-12-09 16:22:32 -08007775 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007776 }
7777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007778 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7779 // assume our apps are happy - lazy create the list
7780 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7781
7782 synchronized (this) {
7783
7784 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007785 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7786 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007787 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7788 // This one's in trouble, so we'll generate a report for it
7789 // crashes are higher priority (in case there's a crash *and* an anr)
7790 ActivityManager.ProcessErrorStateInfo report = null;
7791 if (app.crashing) {
7792 report = app.crashingReport;
7793 } else if (app.notResponding) {
7794 report = app.notRespondingReport;
7795 }
7796
7797 if (report != null) {
7798 if (errList == null) {
7799 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7800 }
7801 errList.add(report);
7802 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007803 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007804 " crashing = " + app.crashing +
7805 " notResponding = " + app.notResponding);
7806 }
7807 }
7808 }
7809 }
7810
7811 return errList;
7812 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007813
7814 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007815 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007816 if (currApp != null) {
7817 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7818 }
7819 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007820 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
7821 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007822 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7823 if (currApp != null) {
7824 currApp.lru = 0;
7825 }
7826 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007827 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007828 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7829 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7830 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7831 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7832 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7833 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7834 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7835 } else {
7836 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7837 }
7838 }
7839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007840 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7841 // Lazy instantiation of list
7842 List<ActivityManager.RunningAppProcessInfo> runList = null;
7843 synchronized (this) {
7844 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007845 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7846 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007847 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7848 // Generate process state info for running application
7849 ActivityManager.RunningAppProcessInfo currApp =
7850 new ActivityManager.RunningAppProcessInfo(app.processName,
7851 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007852 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007853 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007854 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007855 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007856 if (app.persistent) {
7857 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007859 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007860 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007861 currApp.importanceReasonCode = app.adjTypeCode;
7862 if (app.adjSource instanceof ProcessRecord) {
7863 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007864 currApp.importanceReasonImportance = oomAdjToImportance(
7865 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007866 } else if (app.adjSource instanceof ActivityRecord) {
7867 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007868 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7869 }
7870 if (app.adjTarget instanceof ComponentName) {
7871 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7872 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007873 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007874 // + " lru=" + currApp.lru);
7875 if (runList == null) {
7876 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7877 }
7878 runList.add(currApp);
7879 }
7880 }
7881 }
7882 return runList;
7883 }
7884
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007885 public List<ApplicationInfo> getRunningExternalApplications() {
7886 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7887 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7888 if (runningApps != null && runningApps.size() > 0) {
7889 Set<String> extList = new HashSet<String>();
7890 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7891 if (app.pkgList != null) {
7892 for (String pkg : app.pkgList) {
7893 extList.add(pkg);
7894 }
7895 }
7896 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007897 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007898 for (String pkg : extList) {
7899 try {
7900 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7901 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7902 retList.add(info);
7903 }
7904 } catch (RemoteException e) {
7905 }
7906 }
7907 }
7908 return retList;
7909 }
7910
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007911 @Override
7912 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007913 if (checkCallingPermission(android.Manifest.permission.DUMP)
7914 != PackageManager.PERMISSION_GRANTED) {
7915 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7916 + Binder.getCallingPid()
7917 + ", uid=" + Binder.getCallingUid()
7918 + " without permission "
7919 + android.Manifest.permission.DUMP);
7920 return;
7921 }
7922
7923 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007924 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007925 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007926
7927 int opti = 0;
7928 while (opti < args.length) {
7929 String opt = args[opti];
7930 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7931 break;
7932 }
7933 opti++;
7934 if ("-a".equals(opt)) {
7935 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007936 } else if ("-c".equals(opt)) {
7937 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007938 } else if ("-h".equals(opt)) {
7939 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007940 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007941 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007942 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007943 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
7944 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
7945 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007946 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007947 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
Marco Nelissen18cb2872011-11-15 11:19:53 -08007948 pw.println(" provider [COMP_SPEC]: provider client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007949 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007950 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007951 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007952 pw.println(" all: dump all activities");
7953 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007954 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007955 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7956 pw.println(" a partial substring in a component name, a");
7957 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007958 pw.println(" -a: include all available server state.");
7959 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007960 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007961 } else {
7962 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007963 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007964 }
7965
7966 // Is the caller requesting to dump a particular piece of data?
7967 if (opti < args.length) {
7968 String cmd = args[opti];
7969 opti++;
7970 if ("activities".equals(cmd) || "a".equals(cmd)) {
7971 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007972 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007973 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007974 return;
7975 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007976 String[] newArgs;
7977 String name;
7978 if (opti >= args.length) {
7979 name = null;
7980 newArgs = EMPTY_STRING_ARRAY;
7981 } else {
7982 name = args[opti];
7983 opti++;
7984 newArgs = new String[args.length - opti];
7985 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
7986 args.length - opti);
7987 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007988 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007989 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007990 }
7991 return;
7992 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007993 String[] newArgs;
7994 String name;
7995 if (opti >= args.length) {
7996 name = null;
7997 newArgs = EMPTY_STRING_ARRAY;
7998 } else {
7999 name = args[opti];
8000 opti++;
8001 newArgs = new String[args.length - opti];
8002 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8003 args.length - opti);
8004 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008005 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008006 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008007 }
8008 return;
8009 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008010 String[] newArgs;
8011 String name;
8012 if (opti >= args.length) {
8013 name = null;
8014 newArgs = EMPTY_STRING_ARRAY;
8015 } else {
8016 name = args[opti];
8017 opti++;
8018 newArgs = new String[args.length - opti];
8019 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8020 args.length - opti);
8021 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008022 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008023 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008024 }
8025 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008026 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8027 synchronized (this) {
8028 dumpOomLocked(fd, pw, args, opti, true);
8029 }
8030 return;
Marco Nelissen18cb2872011-11-15 11:19:53 -08008031 } else if ("provider".equals(cmd)) {
8032 String[] newArgs;
8033 String name;
8034 if (opti >= args.length) {
8035 name = null;
8036 newArgs = EMPTY_STRING_ARRAY;
8037 } else {
8038 name = args[opti];
8039 opti++;
8040 newArgs = new String[args.length - opti];
8041 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8042 }
8043 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8044 pw.println("No providers match: " + name);
8045 pw.println("Use -h for help.");
8046 }
8047 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008048 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8049 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008050 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008051 }
8052 return;
8053 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008054 String[] newArgs;
8055 String name;
8056 if (opti >= args.length) {
8057 name = null;
8058 newArgs = EMPTY_STRING_ARRAY;
8059 } else {
8060 name = args[opti];
8061 opti++;
8062 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008063 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8064 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008065 }
8066 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8067 pw.println("No services match: " + name);
8068 pw.println("Use -h for help.");
8069 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008070 return;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008071 } else if ("package".equals(cmd)) {
8072 String[] newArgs;
8073 if (opti >= args.length) {
8074 pw.println("package: no package name specified");
8075 pw.println("Use -h for help.");
8076 return;
8077 } else {
8078 dumpPackage = args[opti];
8079 opti++;
8080 newArgs = new String[args.length - opti];
8081 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8082 args.length - opti);
8083 args = newArgs;
8084 opti = 0;
8085 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008086 } else if ("services".equals(cmd) || "s".equals(cmd)) {
8087 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008088 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008089 }
8090 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07008091 } else {
8092 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008093 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8094 pw.println("Bad activity command, or no activities match: " + cmd);
8095 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008096 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008097 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008098 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008099 }
8100
8101 // No piece of data specified, dump everything.
8102 synchronized (this) {
8103 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008104 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008105 if (needSep) {
8106 pw.println(" ");
8107 }
8108 if (dumpAll) {
8109 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008110 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008111 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008112 if (needSep) {
8113 pw.println(" ");
8114 }
8115 if (dumpAll) {
8116 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008117 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008118 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008119 if (needSep) {
8120 pw.println(" ");
8121 }
8122 if (dumpAll) {
8123 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008124 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008125 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008126 if (needSep) {
8127 pw.println(" ");
8128 }
8129 if (dumpAll) {
8130 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008131 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008132 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008133 if (needSep) {
8134 pw.println(" ");
8135 }
8136 if (dumpAll) {
8137 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008138 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008139 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008140 }
8141 }
8142
8143 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008144 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008145 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8146 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008147 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
8148 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008149 pw.println(" ");
8150 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008151 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
8152 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008153 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008154 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008155 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008156 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008157 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008158 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008159 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008160 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008161 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008162 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008163 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008164 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008165 if (mMainStack.mGoingToSleepActivities.size() > 0) {
8166 pw.println(" ");
8167 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008168 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008169 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008170 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008171 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008172 pw.println(" ");
8173 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008174 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008175 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008177
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008178 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008179 if (mMainStack.mPausingActivity != null) {
8180 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
8181 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008182 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008183 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008184 if (dumpAll) {
8185 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8186 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008187 pw.println(" mDismissKeyguardOnNextActivity: "
8188 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008190
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008191 if (mRecentTasks.size() > 0) {
8192 pw.println();
8193 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008194
8195 final int N = mRecentTasks.size();
8196 for (int i=0; i<N; i++) {
8197 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008198 if (dumpPackage != null) {
8199 if (tr.realActivity == null ||
8200 !dumpPackage.equals(tr.realActivity)) {
8201 continue;
8202 }
8203 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008204 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
8205 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008206 if (dumpAll) {
8207 mRecentTasks.get(i).dump(pw, " ");
8208 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008209 }
8210 }
8211
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008212 if (dumpAll) {
8213 pw.println(" ");
8214 pw.println(" mCurTask: " + mCurTask);
8215 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008216
8217 return true;
8218 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008219
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008220 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008221 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008222 boolean needSep = false;
8223 int numPers = 0;
8224
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008225 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8226
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008227 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008228 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8229 final int NA = procs.size();
8230 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008231 ProcessRecord r = procs.valueAt(ia);
8232 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8233 continue;
8234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008235 if (!needSep) {
8236 pw.println(" All known processes:");
8237 needSep = true;
8238 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008239 pw.print(r.persistent ? " *PERS*" : " *APP*");
8240 pw.print(" UID "); pw.print(procs.keyAt(ia));
8241 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008242 r.dump(pw, " ");
8243 if (r.persistent) {
8244 numPers++;
8245 }
8246 }
8247 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008248 }
8249
8250 if (mLruProcesses.size() > 0) {
8251 if (needSep) pw.println(" ");
8252 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008253 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008254 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008255 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008256 needSep = true;
8257 }
8258
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008259 if (dumpAll) {
8260 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008261 boolean printed = false;
8262 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8263 ProcessRecord r = mPidsSelfLocked.valueAt(i);
8264 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8265 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008266 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008267 if (!printed) {
8268 if (needSep) pw.println(" ");
8269 needSep = true;
8270 pw.println(" PID mappings:");
8271 printed = true;
8272 }
8273 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8274 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008275 }
8276 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008277 }
8278
8279 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008280 synchronized (mPidsSelfLocked) {
8281 boolean printed = false;
8282 for (int i=0; i<mForegroundProcesses.size(); i++) {
8283 ProcessRecord r = mPidsSelfLocked.get(
8284 mForegroundProcesses.valueAt(i).pid);
8285 if (dumpPackage != null && (r == null
8286 || !dumpPackage.equals(r.info.packageName))) {
8287 continue;
8288 }
8289 if (!printed) {
8290 if (needSep) pw.println(" ");
8291 needSep = true;
8292 pw.println(" Foreground Processes:");
8293 printed = true;
8294 }
8295 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8296 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008298 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008299 }
8300
8301 if (mPersistentStartingProcesses.size() > 0) {
8302 if (needSep) pw.println(" ");
8303 needSep = true;
8304 pw.println(" Persisent processes that are starting:");
8305 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008306 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008307 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008308
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008309 if (mRemovedProcesses.size() > 0) {
8310 if (needSep) pw.println(" ");
8311 needSep = true;
8312 pw.println(" Processes that are being removed:");
8313 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008314 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008315 }
8316
8317 if (mProcessesOnHold.size() > 0) {
8318 if (needSep) pw.println(" ");
8319 needSep = true;
8320 pw.println(" Processes that are on old until the system is ready:");
8321 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008322 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008324
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008325 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008326
8327 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008328 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008329 long now = SystemClock.uptimeMillis();
8330 for (Map.Entry<String, SparseArray<Long>> procs
8331 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008332 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008333 SparseArray<Long> uids = procs.getValue();
8334 final int N = uids.size();
8335 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008336 int puid = uids.keyAt(i);
8337 ProcessRecord r = mProcessNames.get(pname, puid);
8338 if (dumpPackage != null && (r == null
8339 || !dumpPackage.equals(r.info.packageName))) {
8340 continue;
8341 }
8342 if (!printed) {
8343 if (needSep) pw.println(" ");
8344 needSep = true;
8345 pw.println(" Time since processes crashed:");
8346 printed = true;
8347 }
8348 pw.print(" Process "); pw.print(pname);
8349 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008350 pw.print(": last crashed ");
8351 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008352 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008353 }
8354 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008355 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008356
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008357 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008358 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008359 for (Map.Entry<String, SparseArray<Long>> procs
8360 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008361 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008362 SparseArray<Long> uids = procs.getValue();
8363 final int N = uids.size();
8364 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008365 int puid = uids.keyAt(i);
8366 ProcessRecord r = mProcessNames.get(pname, puid);
8367 if (dumpPackage != null && (r == null
8368 || !dumpPackage.equals(r.info.packageName))) {
8369 continue;
8370 }
8371 if (!printed) {
8372 if (needSep) pw.println(" ");
8373 needSep = true;
8374 pw.println(" Bad processes:");
8375 }
8376 pw.print(" Bad process "); pw.print(pname);
8377 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008378 pw.print(": crashed at time ");
8379 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008380 }
8381 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008383
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008384 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008385 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008386 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn50685602011-12-01 12:23:37 -08008387 if (dumpAll) {
8388 StringBuilder sb = new StringBuilder(128);
8389 sb.append(" mPreviousProcessVisibleTime: ");
8390 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
8391 pw.println(sb);
8392 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07008393 if (mHeavyWeightProcess != null) {
8394 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8395 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008396 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008397 if (dumpAll) {
8398 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008399 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008400 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008401 for (Map.Entry<String, Integer> entry
8402 : mCompatModePackages.getPackages().entrySet()) {
8403 String pkg = entry.getKey();
8404 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008405 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
8406 continue;
8407 }
8408 if (!printed) {
8409 pw.println(" mScreenCompatPackages:");
8410 printed = true;
8411 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008412 pw.print(" "); pw.print(pkg); pw.print(": ");
8413 pw.print(mode); pw.println();
8414 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008415 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008416 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008417 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8418 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8419 || mOrigWaitForDebugger) {
8420 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8421 + " mDebugTransient=" + mDebugTransient
8422 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8423 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008424 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8425 || mProfileFd != null) {
8426 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8427 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8428 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8429 + mAutoStopProfiler);
8430 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008431 if (mAlwaysFinishActivities || mController != null) {
8432 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8433 + " mController=" + mController);
8434 }
8435 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008436 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008437 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008438 + " mProcessesReady=" + mProcessesReady
8439 + " mSystemReady=" + mSystemReady);
8440 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008441 + " mBooted=" + mBooted
8442 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008443 pw.print(" mLastPowerCheckRealtime=");
8444 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8445 pw.println("");
8446 pw.print(" mLastPowerCheckUptime=");
8447 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8448 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008449 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8450 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008451 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008452 pw.println(" mNumServiceProcs=" + mNumServiceProcs
8453 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008454 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008455
8456 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008457 }
8458
Dianne Hackborn287952c2010-09-22 22:34:31 -07008459 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008460 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008461 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008462 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008463 long now = SystemClock.uptimeMillis();
8464 for (int i=0; i<mProcessesToGc.size(); i++) {
8465 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008466 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
8467 continue;
8468 }
8469 if (!printed) {
8470 if (needSep) pw.println(" ");
8471 needSep = true;
8472 pw.println(" Processes that are waiting to GC:");
8473 printed = true;
8474 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008475 pw.print(" Process "); pw.println(proc);
8476 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8477 pw.print(", last gced=");
8478 pw.print(now-proc.lastRequestedGc);
8479 pw.print(" ms ago, last lowMem=");
8480 pw.print(now-proc.lastLowMemory);
8481 pw.println(" ms ago");
8482
8483 }
8484 }
8485 return needSep;
8486 }
8487
8488 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8489 int opti, boolean dumpAll) {
8490 boolean needSep = false;
8491
8492 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008493 if (needSep) pw.println(" ");
8494 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008495 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008496 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008497 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008498 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8499 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8500 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8501 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8502 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008503 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008504 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008505 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008506 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008507 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008508 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008509
8510 if (needSep) pw.println(" ");
8511 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008512 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008513 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008514 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008515 needSep = true;
8516 }
8517
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008518 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008519
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008520 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008521 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008522 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008523 if (mHeavyWeightProcess != null) {
8524 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8525 }
8526
8527 return true;
8528 }
8529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008530 /**
8531 * There are three ways to call this:
8532 * - no service specified: dump all the services
8533 * - a flattened component name that matched an existing service was specified as the
8534 * first arg: dump that one service
8535 * - the first arg isn't the flattened component name of an existing service:
8536 * dump all services whose component contains the first arg as a substring
8537 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008538 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8539 int opti, boolean dumpAll) {
8540 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008541
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008542 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008543 synchronized (this) {
8544 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008545 services.add(r1);
8546 }
8547 }
8548 } else {
8549 ComponentName componentName = name != null
8550 ? ComponentName.unflattenFromString(name) : null;
8551 int objectId = 0;
8552 if (componentName == null) {
8553 // Not a '/' separated full component name; maybe an object ID?
8554 try {
8555 objectId = Integer.parseInt(name, 16);
8556 name = null;
8557 componentName = null;
8558 } catch (RuntimeException e) {
8559 }
8560 }
8561
8562 synchronized (this) {
8563 for (ServiceRecord r1 : mServices.values()) {
8564 if (componentName != null) {
8565 if (r1.name.equals(componentName)) {
8566 services.add(r1);
8567 }
8568 } else if (name != null) {
8569 if (r1.name.flattenToString().contains(name)) {
8570 services.add(r1);
8571 }
8572 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008573 services.add(r1);
8574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008575 }
8576 }
8577 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008578
8579 if (services.size() <= 0) {
8580 return false;
8581 }
8582
8583 boolean needSep = false;
8584 for (int i=0; i<services.size(); i++) {
8585 if (needSep) {
8586 pw.println();
8587 }
8588 needSep = true;
8589 dumpService("", fd, pw, services.get(i), args, dumpAll);
8590 }
8591 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008592 }
8593
8594 /**
8595 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8596 * there is a thread associated with the service.
8597 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008598 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8599 final ServiceRecord r, String[] args, boolean dumpAll) {
8600 String innerPrefix = prefix + " ";
8601 synchronized (this) {
8602 pw.print(prefix); pw.print("SERVICE ");
8603 pw.print(r.shortName); pw.print(" ");
8604 pw.print(Integer.toHexString(System.identityHashCode(r)));
8605 pw.print(" pid=");
8606 if (r.app != null) pw.println(r.app.pid);
8607 else pw.println("(not running)");
8608 if (dumpAll) {
8609 r.dump(pw, innerPrefix);
8610 }
8611 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008612 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008613 pw.print(prefix); pw.println(" Client:");
8614 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008615 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008616 TransferPipe tp = new TransferPipe();
8617 try {
8618 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8619 tp.setBufferPrefix(prefix + " ");
8620 tp.go(fd);
8621 } finally {
8622 tp.kill();
8623 }
8624 } catch (IOException e) {
8625 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008626 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008627 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008628 }
8629 }
8630 }
8631
Marco Nelissen18cb2872011-11-15 11:19:53 -08008632 /**
8633 * There are three ways to call this:
8634 * - no provider specified: dump all the providers
8635 * - a flattened component name that matched an existing provider was specified as the
8636 * first arg: dump that one provider
8637 * - the first arg isn't the flattened component name of an existing provider:
8638 * dump all providers whose component contains the first arg as a substring
8639 */
8640 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8641 int opti, boolean dumpAll) {
8642 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
8643
8644 if ("all".equals(name)) {
8645 synchronized (this) {
8646 for (ContentProviderRecord r1 : mProvidersByClass.values()) {
8647 providers.add(r1);
8648 }
8649 }
8650 } else {
8651 ComponentName componentName = name != null
8652 ? ComponentName.unflattenFromString(name) : null;
8653 int objectId = 0;
8654 if (componentName == null) {
8655 // Not a '/' separated full component name; maybe an object ID?
8656 try {
8657 objectId = Integer.parseInt(name, 16);
8658 name = null;
8659 componentName = null;
8660 } catch (RuntimeException e) {
8661 }
8662 }
8663
8664 synchronized (this) {
8665 for (ContentProviderRecord r1 : mProvidersByClass.values()) {
8666 if (componentName != null) {
8667 if (r1.name.equals(componentName)) {
8668 providers.add(r1);
8669 }
8670 } else if (name != null) {
8671 if (r1.name.flattenToString().contains(name)) {
8672 providers.add(r1);
8673 }
8674 } else if (System.identityHashCode(r1) == objectId) {
8675 providers.add(r1);
8676 }
8677 }
8678 }
8679 }
8680
8681 if (providers.size() <= 0) {
8682 return false;
8683 }
8684
8685 boolean needSep = false;
8686 for (int i=0; i<providers.size(); i++) {
8687 if (needSep) {
8688 pw.println();
8689 }
8690 needSep = true;
8691 dumpProvider("", fd, pw, providers.get(i), args, dumpAll);
8692 }
8693 return true;
8694 }
8695
8696 /**
8697 * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider if
8698 * there is a thread associated with the provider.
8699 */
8700 private void dumpProvider(String prefix, FileDescriptor fd, PrintWriter pw,
8701 final ContentProviderRecord r, String[] args, boolean dumpAll) {
8702 String innerPrefix = prefix + " ";
8703 synchronized (this) {
8704 pw.print(prefix); pw.print("PROVIDER ");
8705 pw.print(r);
8706 pw.print(" pid=");
8707 if (r.proc != null) pw.println(r.proc.pid);
8708 else pw.println("(not running)");
8709 if (dumpAll) {
8710 r.dump(pw, innerPrefix);
8711 }
8712 }
8713 if (r.proc != null && r.proc.thread != null) {
8714 pw.println(" Client:");
8715 pw.flush();
8716 try {
8717 TransferPipe tp = new TransferPipe();
8718 try {
8719 r.proc.thread.dumpProvider(
8720 tp.getWriteFd().getFileDescriptor(), r.provider.asBinder(), args);
8721 tp.setBufferPrefix(" ");
8722 // Short timeout, since blocking here can
8723 // deadlock with the application.
8724 tp.go(fd, 2000);
8725 } finally {
8726 tp.kill();
8727 }
8728 } catch (IOException ex) {
8729 pw.println(" Failure while dumping the provider: " + ex);
8730 } catch (RemoteException ex) {
8731 pw.println(" Got a RemoteException while dumping the service");
8732 }
8733 }
8734 }
8735
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008736 static class ItemMatcher {
8737 ArrayList<ComponentName> components;
8738 ArrayList<String> strings;
8739 ArrayList<Integer> objects;
8740 boolean all;
8741
8742 ItemMatcher() {
8743 all = true;
8744 }
8745
8746 void build(String name) {
8747 ComponentName componentName = ComponentName.unflattenFromString(name);
8748 if (componentName != null) {
8749 if (components == null) {
8750 components = new ArrayList<ComponentName>();
8751 }
8752 components.add(componentName);
8753 all = false;
8754 } else {
8755 int objectId = 0;
8756 // Not a '/' separated full component name; maybe an object ID?
8757 try {
8758 objectId = Integer.parseInt(name, 16);
8759 if (objects == null) {
8760 objects = new ArrayList<Integer>();
8761 }
8762 objects.add(objectId);
8763 all = false;
8764 } catch (RuntimeException e) {
8765 // Not an integer; just do string match.
8766 if (strings == null) {
8767 strings = new ArrayList<String>();
8768 }
8769 strings.add(name);
8770 all = false;
8771 }
8772 }
8773 }
8774
8775 int build(String[] args, int opti) {
8776 for (; opti<args.length; opti++) {
8777 String name = args[opti];
8778 if ("--".equals(name)) {
8779 return opti+1;
8780 }
8781 build(name);
8782 }
8783 return opti;
8784 }
8785
8786 boolean match(Object object, ComponentName comp) {
8787 if (all) {
8788 return true;
8789 }
8790 if (components != null) {
8791 for (int i=0; i<components.size(); i++) {
8792 if (components.get(i).equals(comp)) {
8793 return true;
8794 }
8795 }
8796 }
8797 if (objects != null) {
8798 for (int i=0; i<objects.size(); i++) {
8799 if (System.identityHashCode(object) == objects.get(i)) {
8800 return true;
8801 }
8802 }
8803 }
8804 if (strings != null) {
8805 String flat = comp.flattenToString();
8806 for (int i=0; i<strings.size(); i++) {
8807 if (flat.contains(strings.get(i))) {
8808 return true;
8809 }
8810 }
8811 }
8812 return false;
8813 }
8814 }
8815
Dianne Hackborn625ac272010-09-17 18:29:22 -07008816 /**
8817 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008818 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008819 * - the cmd arg isn't the flattened component name of an existing activity:
8820 * dump all activity whose component contains the cmd as a substring
8821 * - A hex number of the ActivityRecord object instance.
8822 */
8823 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8824 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008825 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008826
8827 if ("all".equals(name)) {
8828 synchronized (this) {
8829 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008830 activities.add(r1);
8831 }
8832 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008833 } else if ("top".equals(name)) {
8834 synchronized (this) {
8835 final int N = mMainStack.mHistory.size();
8836 if (N > 0) {
8837 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8838 }
8839 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008840 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008841 ItemMatcher matcher = new ItemMatcher();
8842 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008843
8844 synchronized (this) {
8845 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008846 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008847 activities.add(r1);
8848 }
8849 }
8850 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008851 }
8852
8853 if (activities.size() <= 0) {
8854 return false;
8855 }
8856
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008857 String[] newArgs = new String[args.length - opti];
8858 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8859
Dianne Hackborn30d71892010-12-11 10:37:55 -08008860 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008861 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008862 for (int i=activities.size()-1; i>=0; i--) {
8863 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008864 if (needSep) {
8865 pw.println();
8866 }
8867 needSep = true;
8868 synchronized (this) {
8869 if (lastTask != r.task) {
8870 lastTask = r.task;
8871 pw.print("TASK "); pw.print(lastTask.affinity);
8872 pw.print(" id="); pw.println(lastTask.taskId);
8873 if (dumpAll) {
8874 lastTask.dump(pw, " ");
8875 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008876 }
8877 }
8878 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008879 }
8880 return true;
8881 }
8882
8883 /**
8884 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8885 * there is a thread associated with the activity.
8886 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008887 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008888 final ActivityRecord r, String[] args, boolean dumpAll) {
8889 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008890 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008891 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8892 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8893 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008894 if (r.app != null) pw.println(r.app.pid);
8895 else pw.println("(not running)");
8896 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008897 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008898 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008899 }
8900 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008901 // flush anything that is already in the PrintWriter since the thread is going
8902 // to write to the file descriptor directly
8903 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008904 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008905 TransferPipe tp = new TransferPipe();
8906 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08008907 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
8908 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008909 tp.go(fd);
8910 } finally {
8911 tp.kill();
8912 }
8913 } catch (IOException e) {
8914 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008915 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008916 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008917 }
8918 }
8919 }
8920
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008921 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008922 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008923 boolean needSep = false;
8924
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008925 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008926 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008927 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008928 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008929 Iterator it = mRegisteredReceivers.values().iterator();
8930 while (it.hasNext()) {
8931 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008932 if (dumpPackage != null && (r.app == null ||
8933 !dumpPackage.equals(r.app.info.packageName))) {
8934 continue;
8935 }
8936 if (!printed) {
8937 pw.println(" Registered Receivers:");
8938 needSep = true;
8939 printed = true;
8940 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008941 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008942 r.dump(pw, " ");
8943 }
8944 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008945
8946 if (mReceiverResolver.dump(pw, needSep ?
8947 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
8948 " ", dumpPackage, false)) {
8949 needSep = true;
8950 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008951 }
8952
8953 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8954 || mPendingBroadcast != null) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008955 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008956 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008957 BroadcastRecord br = mParallelBroadcasts.get(i);
8958 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8959 continue;
8960 }
8961 if (!printed) {
8962 if (needSep) {
8963 pw.println();
8964 }
8965 needSep = true;
8966 pw.println(" Active broadcasts:");
8967 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008968 pw.println(" Broadcast #" + i + ":");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008969 br.dump(pw, " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008970 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008971 printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008972 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008973 BroadcastRecord br = mOrderedBroadcasts.get(i);
8974 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8975 continue;
8976 }
8977 if (!printed) {
8978 if (needSep) {
8979 pw.println();
8980 }
8981 needSep = true;
8982 pw.println(" Active ordered broadcasts:");
8983 }
8984 pw.println(" Ordered Broadcast #" + i + ":");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008985 mOrderedBroadcasts.get(i).dump(pw, " ");
8986 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008987 if (dumpPackage == null || (mPendingBroadcast != null
8988 && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
8989 if (needSep) {
8990 pw.println();
8991 }
8992 pw.println(" Pending broadcast:");
8993 if (mPendingBroadcast != null) {
8994 mPendingBroadcast.dump(pw, " ");
8995 } else {
8996 pw.println(" (null)");
8997 }
8998 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008999 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009000 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009001
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009002 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009003 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
9004 BroadcastRecord r = mBroadcastHistory[i];
9005 if (r == null) {
9006 break;
9007 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009008 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
9009 continue;
9010 }
9011 if (!printed) {
9012 if (needSep) {
9013 pw.println();
9014 }
9015 needSep = true;
9016 pw.println(" Historical broadcasts:");
9017 printed = true;
9018 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009019 if (dumpAll) {
9020 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
9021 r.dump(pw, " ");
9022 } else {
9023 if (i >= 50) {
9024 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08009025 break;
9026 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009027 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08009028 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009029 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009030 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009031
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009032 if (mStickyBroadcasts != null && dumpPackage == null) {
9033 if (needSep) {
9034 pw.println();
9035 }
9036 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009037 pw.println(" Sticky broadcasts:");
9038 StringBuilder sb = new StringBuilder(128);
9039 for (Map.Entry<String, ArrayList<Intent>> ent
9040 : mStickyBroadcasts.entrySet()) {
9041 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009042 if (dumpAll) {
9043 pw.println(":");
9044 ArrayList<Intent> intents = ent.getValue();
9045 final int N = intents.size();
9046 for (int i=0; i<N; i++) {
9047 sb.setLength(0);
9048 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009049 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009050 pw.println(sb.toString());
9051 Bundle bundle = intents.get(i).getExtras();
9052 if (bundle != null) {
9053 pw.print(" ");
9054 pw.println(bundle.toString());
9055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009056 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009057 } else {
9058 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009059 }
9060 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009061 needSep = true;
9062 }
9063
9064 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009065 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009066 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009067 pw.println(" mHandler:");
9068 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009069 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009070 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009071
9072 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009073 }
9074
Marco Nelissen18cb2872011-11-15 11:19:53 -08009075 /**
9076 * Prints a list of ServiceRecords (dumpsys activity services)
9077 */
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009078 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009079 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009080 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009081
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009082 ItemMatcher matcher = new ItemMatcher();
9083 matcher.build(args, opti);
9084
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009085 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
9086 if (mServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009087 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009088 long nowReal = SystemClock.elapsedRealtime();
9089 Iterator<ServiceRecord> it = mServices.values().iterator();
9090 needSep = false;
9091 while (it.hasNext()) {
9092 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009093 if (!matcher.match(r, r.name)) {
9094 continue;
9095 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009096 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9097 continue;
9098 }
9099 if (!printed) {
9100 pw.println(" Active services:");
9101 printed = true;
9102 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009103 if (needSep) {
9104 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009105 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009106 pw.print(" * "); pw.println(r);
9107 if (dumpAll) {
9108 r.dump(pw, " ");
9109 needSep = true;
9110 } else {
9111 pw.print(" app="); pw.println(r.app);
9112 pw.print(" created=");
9113 TimeUtils.formatDuration(r.createTime, nowReal, pw);
9114 pw.print(" started="); pw.print(r.startRequested);
9115 pw.print(" connections="); pw.println(r.connections.size());
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009116 if (r.connections.size() > 0) {
9117 pw.println(" Connections:");
9118 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
9119 for (int i=0; i<clist.size(); i++) {
9120 ConnectionRecord conn = clist.get(i);
9121 pw.print(" ");
9122 pw.print(conn.binding.intent.intent.getIntent().toShortString(
9123 false, false, false));
9124 pw.print(" -> ");
9125 ProcessRecord proc = conn.binding.client;
9126 pw.println(proc != null ? proc.toShortString() : "null");
9127 }
9128 }
9129 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009130 }
9131 if (dumpClient && r.app != null && r.app.thread != null) {
9132 pw.println(" Client:");
9133 pw.flush();
9134 try {
9135 TransferPipe tp = new TransferPipe();
9136 try {
9137 r.app.thread.dumpService(
9138 tp.getWriteFd().getFileDescriptor(), r, args);
9139 tp.setBufferPrefix(" ");
9140 // Short timeout, since blocking here can
9141 // deadlock with the application.
9142 tp.go(fd, 2000);
9143 } finally {
9144 tp.kill();
9145 }
9146 } catch (IOException e) {
9147 pw.println(" Failure while dumping the service: " + e);
9148 } catch (RemoteException e) {
9149 pw.println(" Got a RemoteException while dumping the service");
9150 }
9151 needSep = true;
9152 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009153 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009154 needSep = printed;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009155 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009156
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009157 if (mPendingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009158 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009159 for (int i=0; i<mPendingServices.size(); i++) {
9160 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009161 if (!matcher.match(r, r.name)) {
9162 continue;
9163 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009164 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9165 continue;
9166 }
9167 if (!printed) {
9168 if (needSep) pw.println(" ");
9169 needSep = true;
9170 pw.println(" Pending services:");
9171 printed = true;
9172 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009173 pw.print(" * Pending "); pw.println(r);
9174 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009175 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009176 needSep = true;
9177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009178
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009179 if (mRestartingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009180 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009181 for (int i=0; i<mRestartingServices.size(); i++) {
9182 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009183 if (!matcher.match(r, r.name)) {
9184 continue;
9185 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009186 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9187 continue;
9188 }
9189 if (!printed) {
9190 if (needSep) pw.println(" ");
9191 needSep = true;
9192 pw.println(" Restarting services:");
9193 printed = true;
9194 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009195 pw.print(" * Restarting "); pw.println(r);
9196 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009197 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009198 needSep = true;
9199 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009200
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009201 if (mStoppingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009202 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009203 for (int i=0; i<mStoppingServices.size(); i++) {
9204 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009205 if (!matcher.match(r, r.name)) {
9206 continue;
9207 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009208 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9209 continue;
9210 }
9211 if (!printed) {
9212 if (needSep) pw.println(" ");
9213 needSep = true;
9214 pw.println(" Stopping services:");
9215 printed = true;
9216 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009217 pw.print(" * Stopping "); pw.println(r);
9218 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009219 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009220 needSep = true;
9221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009222
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009223 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009224 if (mServiceConnections.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009225 boolean printed = false;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009226 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009227 = mServiceConnections.values().iterator();
9228 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009229 ArrayList<ConnectionRecord> r = it.next();
9230 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009231 ConnectionRecord cr = r.get(i);
9232 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9233 continue;
9234 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009235 if (dumpPackage != null && (cr.binding.client == null
9236 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9237 continue;
9238 }
9239 if (!printed) {
9240 if (needSep) pw.println(" ");
9241 needSep = true;
9242 pw.println(" Connection bindings to services:");
9243 printed = true;
9244 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009245 pw.print(" * "); pw.println(cr);
9246 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009247 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009248 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009249 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009250 }
9251 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009252
9253 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009254 }
9255
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009256 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009257 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009258 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009259
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009260 ItemMatcher matcher = new ItemMatcher();
9261 matcher.build(args, opti);
9262
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009263 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9264 if (mProvidersByClass.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009265 boolean printed = false;
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009266 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009267 = mProvidersByClass.entrySet().iterator();
9268 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009269 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009270 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009271 ComponentName comp = e.getKey();
9272 String cls = comp.getClassName();
9273 int end = cls.lastIndexOf('.');
9274 if (end > 0 && end < (cls.length()-2)) {
9275 cls = cls.substring(end+1);
9276 }
9277 if (!matcher.match(r, comp)) {
9278 continue;
9279 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009280 if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) {
9281 continue;
9282 }
9283 if (!printed) {
9284 if (needSep) pw.println(" ");
9285 needSep = true;
9286 pw.println(" Published content providers (by class):");
9287 printed = true;
9288 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009289 pw.print(" * "); pw.print(cls); pw.print(" (");
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009290 pw.print(comp.flattenToShortString()); pw.println(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009291 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009292 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009293 } else {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009294 if (r.proc != null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009295 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009296 } else {
9297 pw.println();
9298 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009299 if (r.clients.size() > 0) {
9300 pw.println(" Clients:");
9301 for (ProcessRecord cproc : r.clients) {
9302 pw.print(" - "); pw.println(cproc);
9303 }
9304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009306 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009307 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009308
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009309 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009310 if (mProvidersByName.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009311 boolean printed = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -07009312 Iterator<Map.Entry<String, ContentProviderRecord>> it
9313 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009314 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009315 Map.Entry<String, ContentProviderRecord> e = it.next();
9316 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009317 if (!matcher.match(r, r.name)) {
9318 continue;
9319 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009320 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9321 continue;
9322 }
9323 if (!printed) {
9324 if (needSep) pw.println(" ");
9325 needSep = true;
9326 pw.println(" Authority to provider mappings:");
9327 printed = true;
9328 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009329 pw.print(" "); pw.print(e.getKey()); pw.println(":");
9330 pw.print(" "); pw.println(r);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009331 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009332 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009333 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009334
9335 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009336 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009337 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009338 ContentProviderRecord r = mLaunchingProviders.get(i);
9339 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9340 continue;
9341 }
9342 if (!printed) {
9343 if (needSep) pw.println(" ");
9344 needSep = true;
9345 pw.println(" Launching content providers:");
9346 printed = true;
9347 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009348 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009349 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009350 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009351 }
9352
9353 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009354 if (needSep) pw.println();
9355 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009356 pw.println("Granted Uri Permissions:");
9357 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9358 int uid = mGrantedUriPermissions.keyAt(i);
9359 HashMap<Uri, UriPermission> perms
9360 = mGrantedUriPermissions.valueAt(i);
9361 pw.print(" * UID "); pw.print(uid);
9362 pw.println(" holds:");
9363 for (UriPermission perm : perms.values()) {
9364 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009365 if (dumpAll) {
9366 perm.dump(pw, " ");
9367 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009368 }
9369 }
9370 needSep = true;
9371 }
9372
9373 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009374 }
9375
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009376 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009377 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009378 boolean needSep = false;
9379
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009380 if (mIntentSenderRecords.size() > 0) {
9381 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009382 Iterator<WeakReference<PendingIntentRecord>> it
9383 = mIntentSenderRecords.values().iterator();
9384 while (it.hasNext()) {
9385 WeakReference<PendingIntentRecord> ref = it.next();
9386 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009387 if (dumpPackage != null && (rec == null
9388 || !dumpPackage.equals(rec.key.packageName))) {
9389 continue;
9390 }
9391 if (!printed) {
9392 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9393 printed = true;
9394 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009395 needSep = true;
9396 if (rec != null) {
9397 pw.print(" * "); pw.println(rec);
9398 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009399 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009400 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009401 } else {
9402 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009403 }
9404 }
9405 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009406
9407 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009408 }
9409
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009410 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009411 String prefix, String label, boolean complete, boolean brief, boolean client,
9412 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009413 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009414 boolean needNL = false;
9415 final String innerPrefix = prefix + " ";
9416 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009417 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009418 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009419 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9420 continue;
9421 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07009422 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009423 if (needNL) {
9424 pw.println(" ");
9425 needNL = false;
9426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009427 if (lastTask != r.task) {
9428 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009429 pw.print(prefix);
9430 pw.print(full ? "* " : " ");
9431 pw.println(lastTask);
9432 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009433 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009434 } else if (complete) {
9435 // Complete + brief == give a summary. Isn't that obvious?!?
9436 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009437 pw.print(prefix); pw.print(" ");
9438 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009439 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009440 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009441 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009442 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
9443 pw.print(" #"); pw.print(i); pw.print(": ");
9444 pw.println(r);
9445 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009446 r.dump(pw, innerPrefix);
9447 } else if (complete) {
9448 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009449 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009450 if (r.app != null) {
9451 pw.print(innerPrefix); pw.println(r.app);
9452 }
9453 }
9454 if (client && r.app != null && r.app.thread != null) {
9455 // flush anything that is already in the PrintWriter since the thread is going
9456 // to write to the file descriptor directly
9457 pw.flush();
9458 try {
9459 TransferPipe tp = new TransferPipe();
9460 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009461 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9462 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009463 // Short timeout, since blocking here can
9464 // deadlock with the application.
9465 tp.go(fd, 2000);
9466 } finally {
9467 tp.kill();
9468 }
9469 } catch (IOException e) {
9470 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9471 } catch (RemoteException e) {
9472 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9473 }
9474 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009475 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009476 }
9477 }
9478
Dianne Hackborn09c916b2009-12-08 14:50:51 -08009479 private static String buildOomTag(String prefix, String space, int val, int base) {
9480 if (val == base) {
9481 if (space == null) return prefix;
9482 return prefix + " ";
9483 }
9484 return prefix + "+" + Integer.toString(val-base);
9485 }
9486
9487 private static final int dumpProcessList(PrintWriter pw,
9488 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009489 String prefix, String normalLabel, String persistentLabel,
9490 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009491 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009492 final int N = list.size()-1;
9493 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009495 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9496 continue;
9497 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009498 pw.println(String.format("%s%s #%2d: %s",
9499 prefix, (r.persistent ? persistentLabel : normalLabel),
9500 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009501 if (r.persistent) {
9502 numPers++;
9503 }
9504 }
9505 return numPers;
9506 }
9507
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009508 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07009509 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009510 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009511 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009512
Dianne Hackborn905577f2011-09-07 18:31:28 -07009513 ArrayList<Pair<ProcessRecord, Integer>> list
9514 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9515 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009516 ProcessRecord r = origList.get(i);
9517 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9518 continue;
9519 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07009520 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9521 }
9522
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009523 if (list.size() <= 0) {
9524 return false;
9525 }
9526
Dianne Hackborn905577f2011-09-07 18:31:28 -07009527 Comparator<Pair<ProcessRecord, Integer>> comparator
9528 = new Comparator<Pair<ProcessRecord, Integer>>() {
9529 @Override
9530 public int compare(Pair<ProcessRecord, Integer> object1,
9531 Pair<ProcessRecord, Integer> object2) {
9532 if (object1.first.setAdj != object2.first.setAdj) {
9533 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9534 }
9535 if (object1.second.intValue() != object2.second.intValue()) {
9536 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9537 }
9538 return 0;
9539 }
9540 };
9541
9542 Collections.sort(list, comparator);
9543
Dianne Hackborn287952c2010-09-22 22:34:31 -07009544 final long curRealtime = SystemClock.elapsedRealtime();
9545 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9546 final long curUptime = SystemClock.uptimeMillis();
9547 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9548
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009549 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07009550 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009551 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009552 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009553 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009554 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9555 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009556 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9557 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009558 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9559 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009560 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9561 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009562 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009563 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009564 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9565 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9566 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9567 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9568 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9569 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9570 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9571 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009572 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9573 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009574 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9575 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009576 } else {
9577 oomAdj = Integer.toString(r.setAdj);
9578 }
9579 String schedGroup;
9580 switch (r.setSchedGroup) {
9581 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9582 schedGroup = "B";
9583 break;
9584 case Process.THREAD_GROUP_DEFAULT:
9585 schedGroup = "F";
9586 break;
9587 default:
9588 schedGroup = Integer.toString(r.setSchedGroup);
9589 break;
9590 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009591 String foreground;
9592 if (r.foregroundActivities) {
9593 foreground = "A";
9594 } else if (r.foregroundServices) {
9595 foreground = "S";
9596 } else {
9597 foreground = " ";
9598 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009599 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009600 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009601 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9602 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009603 if (r.adjSource != null || r.adjTarget != null) {
9604 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009605 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009606 if (r.adjTarget instanceof ComponentName) {
9607 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9608 } else if (r.adjTarget != null) {
9609 pw.print(r.adjTarget.toString());
9610 } else {
9611 pw.print("{null}");
9612 }
9613 pw.print("<=");
9614 if (r.adjSource instanceof ProcessRecord) {
9615 pw.print("Proc{");
9616 pw.print(((ProcessRecord)r.adjSource).toShortString());
9617 pw.println("}");
9618 } else if (r.adjSource != null) {
9619 pw.println(r.adjSource.toString());
9620 } else {
9621 pw.println("{null}");
9622 }
9623 }
9624 if (inclDetails) {
9625 pw.print(prefix);
9626 pw.print(" ");
9627 pw.print("oom: max="); pw.print(r.maxAdj);
9628 pw.print(" hidden="); pw.print(r.hiddenAdj);
9629 pw.print(" curRaw="); pw.print(r.curRawAdj);
9630 pw.print(" setRaw="); pw.print(r.setRawAdj);
9631 pw.print(" cur="); pw.print(r.curAdj);
9632 pw.print(" set="); pw.println(r.setAdj);
9633 pw.print(prefix);
9634 pw.print(" ");
9635 pw.print("keeping="); pw.print(r.keeping);
9636 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009637 pw.print(" empty="); pw.print(r.empty);
9638 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009639
9640 if (!r.keeping) {
9641 if (r.lastWakeTime != 0) {
9642 long wtime;
9643 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9644 synchronized (stats) {
9645 wtime = stats.getProcessWakeTime(r.info.uid,
9646 r.pid, curRealtime);
9647 }
9648 long timeUsed = wtime - r.lastWakeTime;
9649 pw.print(prefix);
9650 pw.print(" ");
9651 pw.print("keep awake over ");
9652 TimeUtils.formatDuration(realtimeSince, pw);
9653 pw.print(" used ");
9654 TimeUtils.formatDuration(timeUsed, pw);
9655 pw.print(" (");
9656 pw.print((timeUsed*100)/realtimeSince);
9657 pw.println("%)");
9658 }
9659 if (r.lastCpuTime != 0) {
9660 long timeUsed = r.curCpuTime - r.lastCpuTime;
9661 pw.print(prefix);
9662 pw.print(" ");
9663 pw.print("run cpu over ");
9664 TimeUtils.formatDuration(uptimeSince, pw);
9665 pw.print(" used ");
9666 TimeUtils.formatDuration(timeUsed, pw);
9667 pw.print(" (");
9668 pw.print((timeUsed*100)/uptimeSince);
9669 pw.println("%)");
9670 }
9671 }
9672 }
9673 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009674 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009675 }
9676
Dianne Hackbornb437e092011-08-05 17:50:29 -07009677 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009678 ArrayList<ProcessRecord> procs;
9679 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009680 if (args != null && args.length > start
9681 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009682 procs = new ArrayList<ProcessRecord>();
9683 int pid = -1;
9684 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009685 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009686 } catch (NumberFormatException e) {
9687
9688 }
9689 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9690 ProcessRecord proc = mLruProcesses.get(i);
9691 if (proc.pid == pid) {
9692 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009693 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009694 procs.add(proc);
9695 }
9696 }
9697 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009698 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009699 return null;
9700 }
9701 } else {
9702 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9703 }
9704 }
9705 return procs;
9706 }
9707
9708 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9709 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009710 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009711 if (procs == null) {
9712 return;
9713 }
9714
9715 long uptime = SystemClock.uptimeMillis();
9716 long realtime = SystemClock.elapsedRealtime();
9717 pw.println("Applications Graphics Acceleration Info:");
9718 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9719
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009720 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9721 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009722 if (r.thread != null) {
9723 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9724 pw.flush();
9725 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009726 TransferPipe tp = new TransferPipe();
9727 try {
9728 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9729 tp.go(fd);
9730 } finally {
9731 tp.kill();
9732 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009733 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009734 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009735 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009736 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009737 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009738 pw.flush();
9739 }
9740 }
9741 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009742 }
9743
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009744 final static class MemItem {
9745 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009746 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009747 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009748 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009749 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009750
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009751 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009752 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009753 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009754 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009755 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009756 }
9757 }
9758
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009759 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -07009760 boolean sort) {
9761 if (sort) {
9762 Collections.sort(items, new Comparator<MemItem>() {
9763 @Override
9764 public int compare(MemItem lhs, MemItem rhs) {
9765 if (lhs.pss < rhs.pss) {
9766 return 1;
9767 } else if (lhs.pss > rhs.pss) {
9768 return -1;
9769 }
9770 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009771 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009772 });
9773 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009774
9775 for (int i=0; i<items.size(); i++) {
9776 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009777 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009778 if (mi.subitems != null) {
9779 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9780 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009781 }
9782 }
9783
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009784 // These are in KB.
9785 static final long[] DUMP_MEM_BUCKETS = new long[] {
9786 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9787 120*1024, 160*1024, 200*1024,
9788 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9789 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9790 };
9791
Dianne Hackborn672342c2011-11-29 11:29:02 -08009792 static final void appendMemBucket(StringBuilder out, long memKB, String label,
9793 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009794 int start = label.lastIndexOf('.');
9795 if (start >= 0) start++;
9796 else start = 0;
9797 int end = label.length();
9798 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9799 if (DUMP_MEM_BUCKETS[i] >= memKB) {
9800 long bucket = DUMP_MEM_BUCKETS[i]/1024;
9801 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -08009802 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009803 out.append(label, start, end);
9804 return;
9805 }
9806 }
9807 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08009808 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009809 out.append(label, start, end);
9810 }
9811
9812 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9813 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9814 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9815 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9816 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9817 };
9818 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9819 "System", "Persistent", "Foreground",
9820 "Visible", "Perceptible", "Heavy Weight",
9821 "Backup", "A Services", "Home", "Previous",
9822 "B Services", "Background"
9823 };
9824
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009825 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009826 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -08009827 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009828 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009829 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009830
9831 int opti = 0;
9832 while (opti < args.length) {
9833 String opt = args[opti];
9834 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9835 break;
9836 }
9837 opti++;
9838 if ("-a".equals(opt)) {
9839 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009840 } else if ("--oom".equals(opt)) {
9841 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009842 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009843 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009844 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009845 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009846 pw.println("If [process] is specified it can be the name or ");
9847 pw.println("pid of a specific process to dump.");
9848 return;
9849 } else {
9850 pw.println("Unknown argument: " + opt + "; use -h for help");
9851 }
9852 }
9853
9854 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009855 if (procs == null) {
9856 return;
9857 }
9858
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009859 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009860 long uptime = SystemClock.uptimeMillis();
9861 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009862
9863 if (procs.size() == 1 || isCheckinRequest) {
9864 dumpAll = true;
9865 }
9866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009867 if (isCheckinRequest) {
9868 // short checkin version
9869 pw.println(uptime + "," + realtime);
9870 pw.flush();
9871 } else {
9872 pw.println("Applications Memory Usage (kB):");
9873 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9874 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009875
Dianne Hackbornb437e092011-08-05 17:50:29 -07009876 String[] innerArgs = new String[args.length-opti];
9877 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9878
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009879 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9880 long nativePss=0, dalvikPss=0, otherPss=0;
9881 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9882
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009883 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
9884 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
9885 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009886
9887 long totalPss = 0;
9888
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009889 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9890 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009891 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009892 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009893 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9894 pw.flush();
9895 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009896 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009897 if (dumpAll) {
9898 try {
9899 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9900 } catch (RemoteException e) {
9901 if (!isCheckinRequest) {
9902 pw.println("Got RemoteException!");
9903 pw.flush();
9904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009905 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009906 } else {
9907 mi = new Debug.MemoryInfo();
9908 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009909 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009910
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009911 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009912 long myTotalPss = mi.getTotalPss();
9913 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009914 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009915 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009916 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009917
9918 nativePss += mi.nativePss;
9919 dalvikPss += mi.dalvikPss;
9920 otherPss += mi.otherPss;
9921 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9922 long mem = mi.getOtherPss(j);
9923 miscPss[j] += mem;
9924 otherPss -= mem;
9925 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009926
9927 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009928 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
9929 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009930 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009931 if (oomProcs[oomIndex] == null) {
9932 oomProcs[oomIndex] = new ArrayList<MemItem>();
9933 }
9934 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009935 break;
9936 }
9937 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009938 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009939 }
9940 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009941
9942 if (!isCheckinRequest && procs.size() > 1) {
9943 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9944
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009945 catMems.add(new MemItem("Native", "Native", nativePss, -1));
9946 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
9947 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009948 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009949 String label = Debug.MemoryInfo.getOtherLabel(j);
9950 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009951 }
9952
Dianne Hackbornb437e092011-08-05 17:50:29 -07009953 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9954 for (int j=0; j<oomPss.length; j++) {
9955 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009956 String label = DUMP_MEM_OOM_LABEL[j];
9957 MemItem item = new MemItem(label, label, oomPss[j],
9958 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009959 item.subitems = oomProcs[j];
9960 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009961 }
9962 }
9963
Dianne Hackborn672342c2011-11-29 11:29:02 -08009964 if (outTag != null || outStack != null) {
9965 if (outTag != null) {
9966 appendMemBucket(outTag, totalPss, "total", false);
9967 }
9968 if (outStack != null) {
9969 appendMemBucket(outStack, totalPss, "total", true);
9970 }
9971 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009972 for (int i=0; i<oomMems.size(); i++) {
9973 MemItem miCat = oomMems.get(i);
9974 if (miCat.subitems == null || miCat.subitems.size() < 1) {
9975 continue;
9976 }
9977 if (miCat.id < ProcessList.SERVICE_ADJ
9978 || miCat.id == ProcessList.HOME_APP_ADJ
9979 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009980 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
9981 outTag.append(" / ");
9982 }
9983 if (outStack != null) {
9984 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
9985 if (firstLine) {
9986 outStack.append(":");
9987 firstLine = false;
9988 }
9989 outStack.append("\n\t at ");
9990 } else {
9991 outStack.append("$");
9992 }
9993 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009994 for (int j=0; j<miCat.subitems.size(); j++) {
9995 MemItem mi = miCat.subitems.get(j);
9996 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009997 if (outTag != null) {
9998 outTag.append(" ");
9999 }
10000 if (outStack != null) {
10001 outStack.append("$");
10002 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010003 }
Dianne Hackborn672342c2011-11-29 11:29:02 -080010004 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10005 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10006 }
10007 if (outStack != null) {
10008 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10009 }
10010 }
10011 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10012 outStack.append("(");
10013 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10014 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10015 outStack.append(DUMP_MEM_OOM_LABEL[k]);
10016 outStack.append(":");
10017 outStack.append(DUMP_MEM_OOM_ADJ[k]);
10018 }
10019 }
10020 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010021 }
10022 }
10023 }
10024 }
10025
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010026 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010027 pw.println();
10028 pw.println("Total PSS by process:");
10029 dumpMemItems(pw, " ", procMems, true);
10030 pw.println();
10031 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010032 pw.println("Total PSS by OOM adjustment:");
10033 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010034 if (!oomOnly) {
10035 PrintWriter out = categoryPw != null ? categoryPw : pw;
10036 out.println();
10037 out.println("Total PSS by category:");
10038 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010039 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010040 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010041 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010043 }
10044
10045 /**
10046 * Searches array of arguments for the specified string
10047 * @param args array of argument strings
10048 * @param value value to search for
10049 * @return true if the value is contained in the array
10050 */
10051 private static boolean scanArgs(String[] args, String value) {
10052 if (args != null) {
10053 for (String arg : args) {
10054 if (value.equals(arg)) {
10055 return true;
10056 }
10057 }
10058 }
10059 return false;
10060 }
10061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010062 private final void killServicesLocked(ProcessRecord app,
10063 boolean allowRestart) {
10064 // Report disconnected services.
10065 if (false) {
10066 // XXX we are letting the client link to the service for
10067 // death notifications.
10068 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010069 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010070 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010071 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010072 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010073 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010074 = r.connections.values().iterator();
10075 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010076 ArrayList<ConnectionRecord> cl = jt.next();
10077 for (int i=0; i<cl.size(); i++) {
10078 ConnectionRecord c = cl.get(i);
10079 if (c.binding.client != app) {
10080 try {
10081 //c.conn.connected(r.className, null);
10082 } catch (Exception e) {
10083 // todo: this should be asynchronous!
10084 Slog.w(TAG, "Exception thrown disconnected servce "
10085 + r.shortName
10086 + " from app " + app.processName, e);
10087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010088 }
10089 }
10090 }
10091 }
10092 }
10093 }
10094 }
10095
10096 // Clean up any connections this application has to other services.
10097 if (app.connections.size() > 0) {
10098 Iterator<ConnectionRecord> it = app.connections.iterator();
10099 while (it.hasNext()) {
10100 ConnectionRecord r = it.next();
10101 removeConnectionLocked(r, app, null);
10102 }
10103 }
10104 app.connections.clear();
10105
10106 if (app.services.size() != 0) {
10107 // Any services running in the application need to be placed
10108 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -070010109 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010110 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010111 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010112 synchronized (sr.stats.getBatteryStats()) {
10113 sr.stats.stopLaunchedLocked();
10114 }
10115 sr.app = null;
10116 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010117 if (mStoppingServices.remove(sr)) {
10118 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10119 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010120
10121 boolean hasClients = sr.bindings.size() > 0;
10122 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010123 Iterator<IntentBindRecord> bindings
10124 = sr.bindings.values().iterator();
10125 while (bindings.hasNext()) {
10126 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010127 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010128 + ": shouldUnbind=" + b.hasBound);
10129 b.binder = null;
10130 b.requested = b.received = b.hasBound = false;
10131 }
10132 }
10133
Dianne Hackborn070783f2010-12-29 16:46:28 -080010134 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10135 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010136 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010137 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010138 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010139 sr.crashCount, sr.shortName, app.pid);
10140 bringDownServiceLocked(sr, true);
10141 } else if (!allowRestart) {
10142 bringDownServiceLocked(sr, true);
10143 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010144 boolean canceled = scheduleServiceRestartLocked(sr, true);
10145
10146 // Should the service remain running? Note that in the
10147 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010148 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010149 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10150 if (sr.pendingStarts.size() == 0) {
10151 sr.startRequested = false;
10152 if (!hasClients) {
10153 // Whoops, no reason to restart!
10154 bringDownServiceLocked(sr, true);
10155 }
10156 }
10157 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010158 }
10159 }
10160
10161 if (!allowRestart) {
10162 app.services.clear();
10163 }
10164 }
10165
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010166 // Make sure we have no more records on the stopping list.
10167 int i = mStoppingServices.size();
10168 while (i > 0) {
10169 i--;
10170 ServiceRecord sr = mStoppingServices.get(i);
10171 if (sr.app == app) {
10172 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010173 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010174 }
10175 }
10176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010177 app.executingServices.clear();
10178 }
10179
10180 private final void removeDyingProviderLocked(ProcessRecord proc,
10181 ContentProviderRecord cpr) {
10182 synchronized (cpr) {
10183 cpr.launchingApp = null;
10184 cpr.notifyAll();
10185 }
10186
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010187 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010188 String names[] = cpr.info.authority.split(";");
10189 for (int j = 0; j < names.length; j++) {
10190 mProvidersByName.remove(names[j]);
10191 }
10192
10193 Iterator<ProcessRecord> cit = cpr.clients.iterator();
10194 while (cit.hasNext()) {
10195 ProcessRecord capp = cit.next();
10196 if (!capp.persistent && capp.thread != null
10197 && capp.pid != 0
10198 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010199 Slog.i(TAG, "Kill " + capp.processName
10200 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010201 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -070010202 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010203 capp.processName, capp.setAdj, "dying provider "
10204 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010205 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010206 }
10207 }
10208
10209 mLaunchingProviders.remove(cpr);
10210 }
10211
10212 /**
10213 * Main code for cleaning up a process when it has gone away. This is
10214 * called both as a result of the process dying, or directly when stopping
10215 * a process when running in single process mode.
10216 */
10217 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010218 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010220 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010221 }
10222
Dianne Hackborn36124872009-10-08 16:22:03 -070010223 mProcessesToGc.remove(app);
10224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010225 // Dismiss any open dialogs.
10226 if (app.crashDialog != null) {
10227 app.crashDialog.dismiss();
10228 app.crashDialog = null;
10229 }
10230 if (app.anrDialog != null) {
10231 app.anrDialog.dismiss();
10232 app.anrDialog = null;
10233 }
10234 if (app.waitDialog != null) {
10235 app.waitDialog.dismiss();
10236 app.waitDialog = null;
10237 }
10238
10239 app.crashing = false;
10240 app.notResponding = false;
10241
10242 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070010243 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010244 app.thread = null;
10245 app.forcingToForeground = null;
10246 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010247 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070010248 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010249 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010250
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010251 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010252
10253 boolean restart = false;
10254
10255 int NL = mLaunchingProviders.size();
10256
10257 // Remove published content providers.
10258 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010259 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010260 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010261 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010262 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010263 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010264
10265 // See if someone is waiting for this provider... in which
10266 // case we don't remove it, but just let it restart.
10267 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010268 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010269 for (; i<NL; i++) {
10270 if (mLaunchingProviders.get(i) == cpr) {
10271 restart = true;
10272 break;
10273 }
10274 }
10275 } else {
10276 i = NL;
10277 }
10278
10279 if (i >= NL) {
10280 removeDyingProviderLocked(app, cpr);
10281 NL = mLaunchingProviders.size();
10282 }
10283 }
10284 app.pubProviders.clear();
10285 }
10286
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010287 // Take care of any launching providers waiting for this process.
10288 if (checkAppInLaunchingProvidersLocked(app, false)) {
10289 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010290 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010292 // Unregister from connected content providers.
10293 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -070010294 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010295 while (it.hasNext()) {
10296 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10297 cpr.clients.remove(app);
10298 }
10299 app.conProviders.clear();
10300 }
10301
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010302 // At this point there may be remaining entries in mLaunchingProviders
10303 // where we were the only one waiting, so they are no longer of use.
10304 // Look for these and clean up if found.
10305 // XXX Commented out for now. Trying to figure out a way to reproduce
10306 // the actual situation to identify what is actually going on.
10307 if (false) {
10308 for (int i=0; i<NL; i++) {
10309 ContentProviderRecord cpr = (ContentProviderRecord)
10310 mLaunchingProviders.get(i);
10311 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
10312 synchronized (cpr) {
10313 cpr.launchingApp = null;
10314 cpr.notifyAll();
10315 }
10316 }
10317 }
10318 }
10319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010320 skipCurrentReceiverLocked(app);
10321
10322 // Unregister any receivers.
10323 if (app.receivers.size() > 0) {
10324 Iterator<ReceiverList> it = app.receivers.iterator();
10325 while (it.hasNext()) {
10326 removeReceiverLocked(it.next());
10327 }
10328 app.receivers.clear();
10329 }
10330
Christopher Tate181fafa2009-05-14 11:12:14 -070010331 // If the app is undergoing backup, tell the backup manager about it
10332 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010333 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070010334 try {
10335 IBackupManager bm = IBackupManager.Stub.asInterface(
10336 ServiceManager.getService(Context.BACKUP_SERVICE));
10337 bm.agentDisconnected(app.info.packageName);
10338 } catch (RemoteException e) {
10339 // can't happen; backup manager is local
10340 }
10341 }
10342
Jeff Sharkey287bd832011-05-28 19:36:26 -070010343 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010345 // If the caller is restarting this app, then leave it in its
10346 // current lists and let the caller take care of it.
10347 if (restarting) {
10348 return;
10349 }
10350
10351 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010352 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010353 "Removing non-persistent process during cleanup: " + app);
10354 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070010355 if (mHeavyWeightProcess == app) {
10356 mHeavyWeightProcess = null;
10357 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10358 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010359 } else if (!app.removed) {
10360 // This app is persistent, so we need to keep its record around.
10361 // If it is not already on the pending app list, add it there
10362 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010363 if (mPersistentStartingProcesses.indexOf(app) < 0) {
10364 mPersistentStartingProcesses.add(app);
10365 restart = true;
10366 }
10367 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010368 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10369 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010370 mProcessesOnHold.remove(app);
10371
The Android Open Source Project4df24232009-03-05 14:34:35 -080010372 if (app == mHomeProcess) {
10373 mHomeProcess = null;
10374 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010375 if (app == mPreviousProcess) {
10376 mPreviousProcess = null;
10377 }
10378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010379 if (restart) {
10380 // We have components that still need to be running in the
10381 // process, so re-launch it.
10382 mProcessNames.put(app.processName, app.info.uid, app);
10383 startProcessLocked(app, "restart", app.processName);
10384 } else if (app.pid > 0 && app.pid != MY_PID) {
10385 // Goodbye!
10386 synchronized (mPidsSelfLocked) {
10387 mPidsSelfLocked.remove(app.pid);
10388 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10389 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010390 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010391 }
10392 }
10393
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010394 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10395 // Look through the content providers we are waiting to have launched,
10396 // and if any run in this process then either schedule a restart of
10397 // the process or kill the client waiting for it if this process has
10398 // gone bad.
10399 int NL = mLaunchingProviders.size();
10400 boolean restart = false;
10401 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010402 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010403 if (cpr.launchingApp == app) {
10404 if (!alwaysBad && !app.bad) {
10405 restart = true;
10406 } else {
10407 removeDyingProviderLocked(app, cpr);
10408 NL = mLaunchingProviders.size();
10409 }
10410 }
10411 }
10412 return restart;
10413 }
10414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010415 // =========================================================
10416 // SERVICES
10417 // =========================================================
10418
10419 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10420 ActivityManager.RunningServiceInfo info =
10421 new ActivityManager.RunningServiceInfo();
10422 info.service = r.name;
10423 if (r.app != null) {
10424 info.pid = r.app.pid;
10425 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010426 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010427 info.process = r.processName;
10428 info.foreground = r.isForeground;
10429 info.activeSince = r.createTime;
10430 info.started = r.startRequested;
10431 info.clientCount = r.connections.size();
10432 info.crashCount = r.crashCount;
10433 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010434 if (r.isForeground) {
10435 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10436 }
10437 if (r.startRequested) {
10438 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10439 }
Dan Egnor42471dd2010-01-07 17:25:22 -080010440 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010441 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10442 }
10443 if (r.app != null && r.app.persistent) {
10444 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10445 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010446
10447 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10448 for (int i=0; i<connl.size(); i++) {
10449 ConnectionRecord conn = connl.get(i);
10450 if (conn.clientLabel != 0) {
10451 info.clientPackage = conn.binding.client.info.packageName;
10452 info.clientLabel = conn.clientLabel;
10453 return info;
10454 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010455 }
10456 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010457 return info;
10458 }
10459
10460 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10461 int flags) {
10462 synchronized (this) {
10463 ArrayList<ActivityManager.RunningServiceInfo> res
10464 = new ArrayList<ActivityManager.RunningServiceInfo>();
10465
10466 if (mServices.size() > 0) {
10467 Iterator<ServiceRecord> it = mServices.values().iterator();
10468 while (it.hasNext() && res.size() < maxNum) {
10469 res.add(makeRunningServiceInfoLocked(it.next()));
10470 }
10471 }
10472
10473 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10474 ServiceRecord r = mRestartingServices.get(i);
10475 ActivityManager.RunningServiceInfo info =
10476 makeRunningServiceInfoLocked(r);
10477 info.restarting = r.nextRestartTime;
10478 res.add(info);
10479 }
10480
10481 return res;
10482 }
10483 }
10484
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010485 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10486 synchronized (this) {
10487 ServiceRecord r = mServices.get(name);
10488 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010489 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
10490 for (int i=0; i<conn.size(); i++) {
10491 if (conn.get(i).clientIntent != null) {
10492 return conn.get(i).clientIntent;
10493 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010494 }
10495 }
10496 }
10497 }
10498 return null;
10499 }
10500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010501 private final ServiceRecord findServiceLocked(ComponentName name,
10502 IBinder token) {
10503 ServiceRecord r = mServices.get(name);
10504 return r == token ? r : null;
10505 }
10506
10507 private final class ServiceLookupResult {
10508 final ServiceRecord record;
10509 final String permission;
10510
10511 ServiceLookupResult(ServiceRecord _record, String _permission) {
10512 record = _record;
10513 permission = _permission;
10514 }
10515 };
10516
10517 private ServiceLookupResult findServiceLocked(Intent service,
10518 String resolvedType) {
10519 ServiceRecord r = null;
10520 if (service.getComponent() != null) {
10521 r = mServices.get(service.getComponent());
10522 }
10523 if (r == null) {
10524 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10525 r = mServicesByIntent.get(filter);
10526 }
10527
10528 if (r == null) {
10529 try {
10530 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010531 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010532 service, resolvedType, 0);
10533 ServiceInfo sInfo =
10534 rInfo != null ? rInfo.serviceInfo : null;
10535 if (sInfo == null) {
10536 return null;
10537 }
10538
10539 ComponentName name = new ComponentName(
10540 sInfo.applicationInfo.packageName, sInfo.name);
10541 r = mServices.get(name);
10542 } catch (RemoteException ex) {
10543 // pm is in same process, this will never happen.
10544 }
10545 }
10546 if (r != null) {
10547 int callingPid = Binder.getCallingPid();
10548 int callingUid = Binder.getCallingUid();
10549 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010550 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010551 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010552 if (!r.exported) {
10553 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10554 + " from pid=" + callingPid
10555 + ", uid=" + callingUid
10556 + " that is not exported from uid " + r.appInfo.uid);
10557 return new ServiceLookupResult(null, "not exported from uid "
10558 + r.appInfo.uid);
10559 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010560 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010561 + " from pid=" + callingPid
10562 + ", uid=" + callingUid
10563 + " requires " + r.permission);
10564 return new ServiceLookupResult(null, r.permission);
10565 }
10566 return new ServiceLookupResult(r, null);
10567 }
10568 return null;
10569 }
10570
10571 private class ServiceRestarter implements Runnable {
10572 private ServiceRecord mService;
10573
10574 void setService(ServiceRecord service) {
10575 mService = service;
10576 }
10577
10578 public void run() {
10579 synchronized(ActivityManagerService.this) {
10580 performServiceRestartLocked(mService);
10581 }
10582 }
10583 }
10584
10585 private ServiceLookupResult retrieveServiceLocked(Intent service,
10586 String resolvedType, int callingPid, int callingUid) {
10587 ServiceRecord r = null;
10588 if (service.getComponent() != null) {
10589 r = mServices.get(service.getComponent());
10590 }
10591 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10592 r = mServicesByIntent.get(filter);
10593 if (r == null) {
10594 try {
10595 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010596 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010597 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010598 ServiceInfo sInfo =
10599 rInfo != null ? rInfo.serviceInfo : null;
10600 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010601 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010602 ": not found");
10603 return null;
10604 }
10605
10606 ComponentName name = new ComponentName(
10607 sInfo.applicationInfo.packageName, sInfo.name);
10608 r = mServices.get(name);
10609 if (r == null) {
10610 filter = new Intent.FilterComparison(service.cloneFilter());
10611 ServiceRestarter res = new ServiceRestarter();
10612 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10613 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10614 synchronized (stats) {
10615 ss = stats.getServiceStatsLocked(
10616 sInfo.applicationInfo.uid, sInfo.packageName,
10617 sInfo.name);
10618 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080010619 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010620 res.setService(r);
10621 mServices.put(name, r);
10622 mServicesByIntent.put(filter, r);
10623
10624 // Make sure this component isn't in the pending list.
10625 int N = mPendingServices.size();
10626 for (int i=0; i<N; i++) {
10627 ServiceRecord pr = mPendingServices.get(i);
10628 if (pr.name.equals(name)) {
10629 mPendingServices.remove(i);
10630 i--;
10631 N--;
10632 }
10633 }
10634 }
10635 } catch (RemoteException ex) {
10636 // pm is in same process, this will never happen.
10637 }
10638 }
10639 if (r != null) {
10640 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010641 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010642 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010643 if (!r.exported) {
10644 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10645 + " from pid=" + callingPid
10646 + ", uid=" + callingUid
10647 + " that is not exported from uid " + r.appInfo.uid);
10648 return new ServiceLookupResult(null, "not exported from uid "
10649 + r.appInfo.uid);
10650 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010651 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010652 + " from pid=" + callingPid
10653 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010654 + " requires " + r.permission);
10655 return new ServiceLookupResult(null, r.permission);
10656 }
10657 return new ServiceLookupResult(r, null);
10658 }
10659 return null;
10660 }
10661
Dianne Hackborn287952c2010-09-22 22:34:31 -070010662 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
10663 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
10664 + why + " of " + r + " in app " + r.app);
10665 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
10666 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010667 long now = SystemClock.uptimeMillis();
10668 if (r.executeNesting == 0 && r.app != null) {
10669 if (r.app.executingServices.size() == 0) {
10670 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10671 msg.obj = r.app;
10672 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10673 }
10674 r.app.executingServices.add(r);
10675 }
10676 r.executeNesting++;
10677 r.executingStart = now;
10678 }
10679
10680 private final void sendServiceArgsLocked(ServiceRecord r,
10681 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010682 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010683 if (N == 0) {
10684 return;
10685 }
10686
Dianne Hackborn39792d22010-08-19 18:01:52 -070010687 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010688 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010689 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010690 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10691 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010692 if (si.intent == null && N > 1) {
10693 // If somehow we got a dummy null intent in the middle,
10694 // then skip it. DO NOT skip a null intent when it is
10695 // the only one in the list -- this is to support the
10696 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010697 continue;
10698 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010699 si.deliveredTime = SystemClock.uptimeMillis();
10700 r.deliveredStarts.add(si);
10701 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010702 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010703 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010704 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010705 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010706 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010707 if (!oomAdjusted) {
10708 oomAdjusted = true;
10709 updateOomAdjLocked(r.app);
10710 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010711 int flags = 0;
10712 if (si.deliveryCount > 0) {
10713 flags |= Service.START_FLAG_RETRY;
10714 }
10715 if (si.doneExecutingCount > 0) {
10716 flags |= Service.START_FLAG_REDELIVERY;
10717 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010718 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010719 } catch (RemoteException e) {
10720 // Remote process gone... we'll let the normal cleanup take
10721 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010722 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010723 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010724 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010725 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010726 break;
10727 }
10728 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010729 }
10730
10731 private final boolean requestServiceBindingLocked(ServiceRecord r,
10732 IntentBindRecord i, boolean rebind) {
10733 if (r.app == null || r.app.thread == null) {
10734 // If service is not currently running, can't yet bind.
10735 return false;
10736 }
10737 if ((!i.requested || rebind) && i.apps.size() > 0) {
10738 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010739 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010740 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10741 if (!rebind) {
10742 i.requested = true;
10743 }
10744 i.hasBound = true;
10745 i.doRebind = false;
10746 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010747 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010748 return false;
10749 }
10750 }
10751 return true;
10752 }
10753
10754 private final void requestServiceBindingsLocked(ServiceRecord r) {
10755 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10756 while (bindings.hasNext()) {
10757 IntentBindRecord i = bindings.next();
10758 if (!requestServiceBindingLocked(r, i, false)) {
10759 break;
10760 }
10761 }
10762 }
10763
10764 private final void realStartServiceLocked(ServiceRecord r,
10765 ProcessRecord app) throws RemoteException {
10766 if (app.thread == null) {
10767 throw new RemoteException();
10768 }
10769
10770 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010771 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010772
10773 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010774 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010775 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010776
10777 boolean created = false;
10778 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010779 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010780 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010781 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010782 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010783 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010784 synchronized (r.stats.getBatteryStats()) {
10785 r.stats.startLaunchedLocked();
10786 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010787 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010788 app.thread.scheduleCreateService(r, r.serviceInfo,
10789 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010790 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010791 created = true;
10792 } finally {
10793 if (!created) {
10794 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010795 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010796 }
10797 }
10798
10799 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010800
10801 // If the service is in the started state, and there are no
10802 // pending arguments, then fake up one so its onStartCommand() will
10803 // be called.
10804 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010805 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10806 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010807 }
10808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010809 sendServiceArgsLocked(r, true);
10810 }
10811
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010812 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10813 boolean allowCancel) {
10814 boolean canceled = false;
10815
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010816 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010817 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010818 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010819
Dianne Hackborn070783f2010-12-29 16:46:28 -080010820 if ((r.serviceInfo.applicationInfo.flags
10821 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10822 minDuration /= 4;
10823 }
10824
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010825 // Any delivered but not yet finished starts should be put back
10826 // on the pending list.
10827 final int N = r.deliveredStarts.size();
10828 if (N > 0) {
10829 for (int i=N-1; i>=0; i--) {
10830 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010831 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010832 if (si.intent == null) {
10833 // We'll generate this again if needed.
10834 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10835 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10836 r.pendingStarts.add(0, si);
10837 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10838 dur *= 2;
10839 if (minDuration < dur) minDuration = dur;
10840 if (resetTime < dur) resetTime = dur;
10841 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010842 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010843 + r.name);
10844 canceled = true;
10845 }
10846 }
10847 r.deliveredStarts.clear();
10848 }
10849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010850 r.totalRestartCount++;
10851 if (r.restartDelay == 0) {
10852 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010853 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010854 } else {
10855 // If it has been a "reasonably long time" since the service
10856 // was started, then reset our restart duration back to
10857 // the beginning, so we don't infinitely increase the duration
10858 // on a service that just occasionally gets killed (which is
10859 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010860 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010861 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010862 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010863 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010864 if ((r.serviceInfo.applicationInfo.flags
10865 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10866 // Services in peristent processes will restart much more
10867 // quickly, since they are pretty important. (Think SystemUI).
10868 r.restartDelay += minDuration/2;
10869 } else {
10870 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10871 if (r.restartDelay < minDuration) {
10872 r.restartDelay = minDuration;
10873 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010874 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010875 }
10876 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010877
10878 r.nextRestartTime = now + r.restartDelay;
10879
10880 // Make sure that we don't end up restarting a bunch of services
10881 // all at the same time.
10882 boolean repeat;
10883 do {
10884 repeat = false;
10885 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10886 ServiceRecord r2 = mRestartingServices.get(i);
10887 if (r2 != r && r.nextRestartTime
10888 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10889 && r.nextRestartTime
10890 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10891 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10892 r.restartDelay = r.nextRestartTime - now;
10893 repeat = true;
10894 break;
10895 }
10896 }
10897 } while (repeat);
10898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010899 if (!mRestartingServices.contains(r)) {
10900 mRestartingServices.add(r);
10901 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010902
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010903 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010905 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010906 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010907 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010908 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010909 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010910 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010911 r.shortName, r.restartDelay);
10912
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010913 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010914 }
10915
10916 final void performServiceRestartLocked(ServiceRecord r) {
10917 if (!mRestartingServices.contains(r)) {
10918 return;
10919 }
10920 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10921 }
10922
10923 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10924 if (r.restartDelay == 0) {
10925 return false;
10926 }
10927 r.resetRestartCounter();
10928 mRestartingServices.remove(r);
10929 mHandler.removeCallbacks(r.restarter);
10930 return true;
10931 }
10932
10933 private final boolean bringUpServiceLocked(ServiceRecord r,
10934 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010935 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010936 //r.dump(" ");
10937
Dianne Hackborn36124872009-10-08 16:22:03 -070010938 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010939 sendServiceArgsLocked(r, false);
10940 return true;
10941 }
10942
10943 if (!whileRestarting && r.restartDelay > 0) {
10944 // If waiting for a restart, then do nothing.
10945 return true;
10946 }
10947
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010948 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010949
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010950 // We are now bringing the service up, so no longer in the
10951 // restarting state.
10952 mRestartingServices.remove(r);
10953
Dianne Hackborne7f97212011-02-24 14:40:20 -080010954 // Service is now being launched, its package can't be stopped.
10955 try {
10956 AppGlobals.getPackageManager().setPackageStoppedState(
10957 r.packageName, false);
10958 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010959 } catch (IllegalArgumentException e) {
10960 Slog.w(TAG, "Failed trying to unstop package "
10961 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010962 }
10963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010964 final String appName = r.processName;
10965 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10966 if (app != null && app.thread != null) {
10967 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010968 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010969 realStartServiceLocked(r, app);
10970 return true;
10971 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010972 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010973 }
10974
10975 // If a dead object exception was thrown -- fall through to
10976 // restart the application.
10977 }
10978
Dianne Hackborn36124872009-10-08 16:22:03 -070010979 // Not running -- get it started, and enqueue this service record
10980 // to be executed when the app comes up.
10981 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10982 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010983 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010984 + r.appInfo.packageName + "/"
10985 + r.appInfo.uid + " for service "
10986 + r.intent.getIntent() + ": process is bad");
10987 bringDownServiceLocked(r, true);
10988 return false;
10989 }
10990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010991 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010992 mPendingServices.add(r);
10993 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010995 return true;
10996 }
10997
10998 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010999 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011000 //r.dump(" ");
11001
11002 // Does it still need to run?
11003 if (!force && r.startRequested) {
11004 return;
11005 }
11006 if (r.connections.size() > 0) {
11007 if (!force) {
11008 // XXX should probably keep a count of the number of auto-create
11009 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011010 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011011 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011012 ArrayList<ConnectionRecord> cr = it.next();
11013 for (int i=0; i<cr.size(); i++) {
11014 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
11015 return;
11016 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011017 }
11018 }
11019 }
11020
11021 // Report to all of the connections that the service is no longer
11022 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011023 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011025 ArrayList<ConnectionRecord> c = it.next();
11026 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011027 ConnectionRecord cr = c.get(i);
11028 // There is still a connection to the service that is
11029 // being brought down. Mark it as dead.
11030 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011031 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011032 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011033 } catch (Exception e) {
11034 Slog.w(TAG, "Failure disconnecting service " + r.name +
11035 " to connection " + c.get(i).conn.asBinder() +
11036 " (in " + c.get(i).binding.client.processName + ")", e);
11037 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011038 }
11039 }
11040 }
11041
11042 // Tell the service that it has been unbound.
11043 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
11044 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
11045 while (it.hasNext()) {
11046 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011047 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011048 + ": hasBound=" + ibr.hasBound);
11049 if (r.app != null && r.app.thread != null && ibr.hasBound) {
11050 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011051 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011052 updateOomAdjLocked(r.app);
11053 ibr.hasBound = false;
11054 r.app.thread.scheduleUnbindService(r,
11055 ibr.intent.getIntent());
11056 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011057 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011058 + r.shortName, e);
11059 serviceDoneExecutingLocked(r, true);
11060 }
11061 }
11062 }
11063 }
11064
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011065 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011066 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011067 System.identityHashCode(r), r.shortName,
11068 (r.app != null) ? r.app.pid : -1);
11069
11070 mServices.remove(r.name);
11071 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011072 r.totalRestartCount = 0;
11073 unscheduleServiceRestartLocked(r);
11074
11075 // Also make sure it is not on the pending list.
11076 int N = mPendingServices.size();
11077 for (int i=0; i<N; i++) {
11078 if (mPendingServices.get(i) == r) {
11079 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011080 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011081 i--;
11082 N--;
11083 }
11084 }
11085
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011086 r.cancelNotification();
11087 r.isForeground = false;
11088 r.foregroundId = 0;
11089 r.foregroundNoti = null;
11090
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011091 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070011092 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011093 r.pendingStarts.clear();
11094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011095 if (r.app != null) {
11096 synchronized (r.stats.getBatteryStats()) {
11097 r.stats.stopLaunchedLocked();
11098 }
11099 r.app.services.remove(r);
11100 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011101 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011102 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011103 mStoppingServices.add(r);
11104 updateOomAdjLocked(r.app);
11105 r.app.thread.scheduleStopService(r);
11106 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011107 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011108 + r.shortName, e);
11109 serviceDoneExecutingLocked(r, true);
11110 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011111 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011112 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011113 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011114 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011115 }
11116 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011117 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011118 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011119 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080011120
11121 if (r.bindings.size() > 0) {
11122 r.bindings.clear();
11123 }
11124
11125 if (r.restarter instanceof ServiceRestarter) {
11126 ((ServiceRestarter)r.restarter).setService(null);
11127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011128 }
11129
11130 ComponentName startServiceLocked(IApplicationThread caller,
11131 Intent service, String resolvedType,
11132 int callingPid, int callingUid) {
11133 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011134 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011135 + " type=" + resolvedType + " args=" + service.getExtras());
11136
11137 if (caller != null) {
11138 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11139 if (callerApp == null) {
11140 throw new SecurityException(
11141 "Unable to find app for caller " + caller
11142 + " (pid=" + Binder.getCallingPid()
11143 + ") when starting service " + service);
11144 }
11145 }
11146
11147 ServiceLookupResult res =
11148 retrieveServiceLocked(service, resolvedType,
11149 callingPid, callingUid);
11150 if (res == null) {
11151 return null;
11152 }
11153 if (res.record == null) {
11154 return new ComponentName("!", res.permission != null
11155 ? res.permission : "private to package");
11156 }
11157 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070011158 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
11159 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011160 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011161 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011162 }
11163 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011164 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011165 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070011166 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011167 r.lastActivity = SystemClock.uptimeMillis();
11168 synchronized (r.stats.getBatteryStats()) {
11169 r.stats.startRunningLocked();
11170 }
11171 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11172 return new ComponentName("!", "Service process is bad");
11173 }
11174 return r.name;
11175 }
11176 }
11177
11178 public ComponentName startService(IApplicationThread caller, Intent service,
11179 String resolvedType) {
11180 // Refuse possible leaked file descriptors
11181 if (service != null && service.hasFileDescriptors() == true) {
11182 throw new IllegalArgumentException("File descriptors passed in Intent");
11183 }
11184
11185 synchronized(this) {
11186 final int callingPid = Binder.getCallingPid();
11187 final int callingUid = Binder.getCallingUid();
11188 final long origId = Binder.clearCallingIdentity();
11189 ComponentName res = startServiceLocked(caller, service,
11190 resolvedType, callingPid, callingUid);
11191 Binder.restoreCallingIdentity(origId);
11192 return res;
11193 }
11194 }
11195
11196 ComponentName startServiceInPackage(int uid,
11197 Intent service, String resolvedType) {
11198 synchronized(this) {
11199 final long origId = Binder.clearCallingIdentity();
11200 ComponentName res = startServiceLocked(null, service,
11201 resolvedType, -1, uid);
11202 Binder.restoreCallingIdentity(origId);
11203 return res;
11204 }
11205 }
11206
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011207 private void stopServiceLocked(ServiceRecord service) {
11208 synchronized (service.stats.getBatteryStats()) {
11209 service.stats.stopRunningLocked();
11210 }
11211 service.startRequested = false;
11212 service.callStart = false;
11213 bringDownServiceLocked(service, false);
11214 }
11215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011216 public int stopService(IApplicationThread caller, Intent service,
11217 String resolvedType) {
11218 // Refuse possible leaked file descriptors
11219 if (service != null && service.hasFileDescriptors() == true) {
11220 throw new IllegalArgumentException("File descriptors passed in Intent");
11221 }
11222
11223 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011224 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011225 + " type=" + resolvedType);
11226
11227 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11228 if (caller != null && callerApp == null) {
11229 throw new SecurityException(
11230 "Unable to find app for caller " + caller
11231 + " (pid=" + Binder.getCallingPid()
11232 + ") when stopping service " + service);
11233 }
11234
11235 // If this service is active, make sure it is stopped.
11236 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11237 if (r != null) {
11238 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011239 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011240 try {
11241 stopServiceLocked(r.record);
11242 } finally {
11243 Binder.restoreCallingIdentity(origId);
11244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011245 return 1;
11246 }
11247 return -1;
11248 }
11249 }
11250
11251 return 0;
11252 }
11253
11254 public IBinder peekService(Intent service, String resolvedType) {
11255 // Refuse possible leaked file descriptors
11256 if (service != null && service.hasFileDescriptors() == true) {
11257 throw new IllegalArgumentException("File descriptors passed in Intent");
11258 }
11259
11260 IBinder ret = null;
11261
11262 synchronized(this) {
11263 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11264
11265 if (r != null) {
11266 // r.record is null if findServiceLocked() failed the caller permission check
11267 if (r.record == null) {
11268 throw new SecurityException(
11269 "Permission Denial: Accessing service " + r.record.name
11270 + " from pid=" + Binder.getCallingPid()
11271 + ", uid=" + Binder.getCallingUid()
11272 + " requires " + r.permission);
11273 }
11274 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11275 if (ib != null) {
11276 ret = ib.binder;
11277 }
11278 }
11279 }
11280
11281 return ret;
11282 }
11283
11284 public boolean stopServiceToken(ComponentName className, IBinder token,
11285 int startId) {
11286 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011287 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011288 + " " + token + " startId=" + startId);
11289 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011290 if (r != null) {
11291 if (startId >= 0) {
11292 // Asked to only stop if done with all work. Note that
11293 // to avoid leaks, we will take this as dropping all
11294 // start items up to and including this one.
11295 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11296 if (si != null) {
11297 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011298 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11299 cur.removeUriPermissionsLocked();
11300 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011301 break;
11302 }
11303 }
11304 }
11305
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011306 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011307 return false;
11308 }
11309
11310 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011311 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011312 + " is last, but have " + r.deliveredStarts.size()
11313 + " remaining args");
11314 }
11315 }
11316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011317 synchronized (r.stats.getBatteryStats()) {
11318 r.stats.stopRunningLocked();
11319 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011320 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011321 }
11322 final long origId = Binder.clearCallingIdentity();
11323 bringDownServiceLocked(r, false);
11324 Binder.restoreCallingIdentity(origId);
11325 return true;
11326 }
11327 }
11328 return false;
11329 }
11330
11331 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011332 int id, Notification notification, boolean removeNotification) {
11333 final long origId = Binder.clearCallingIdentity();
11334 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011335 synchronized(this) {
11336 ServiceRecord r = findServiceLocked(className, token);
11337 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011338 if (id != 0) {
11339 if (notification == null) {
11340 throw new IllegalArgumentException("null notification");
11341 }
11342 if (r.foregroundId != id) {
11343 r.cancelNotification();
11344 r.foregroundId = id;
11345 }
11346 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11347 r.foregroundNoti = notification;
11348 r.isForeground = true;
11349 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011350 if (r.app != null) {
11351 updateServiceForegroundLocked(r.app, true);
11352 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011353 } else {
11354 if (r.isForeground) {
11355 r.isForeground = false;
11356 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070011357 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011358 updateServiceForegroundLocked(r.app, true);
11359 }
11360 }
11361 if (removeNotification) {
11362 r.cancelNotification();
11363 r.foregroundId = 0;
11364 r.foregroundNoti = null;
11365 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011366 }
11367 }
11368 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011369 } finally {
11370 Binder.restoreCallingIdentity(origId);
11371 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011372 }
11373
11374 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11375 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070011376 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011377 if (sr.isForeground) {
11378 anyForeground = true;
11379 break;
11380 }
11381 }
11382 if (anyForeground != proc.foregroundServices) {
11383 proc.foregroundServices = anyForeground;
11384 if (oomAdj) {
11385 updateOomAdjLocked();
11386 }
11387 }
11388 }
11389
11390 public int bindService(IApplicationThread caller, IBinder token,
11391 Intent service, String resolvedType,
11392 IServiceConnection connection, int flags) {
11393 // Refuse possible leaked file descriptors
11394 if (service != null && service.hasFileDescriptors() == true) {
11395 throw new IllegalArgumentException("File descriptors passed in Intent");
11396 }
11397
11398 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011399 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011400 + " type=" + resolvedType + " conn=" + connection.asBinder()
11401 + " flags=0x" + Integer.toHexString(flags));
11402 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11403 if (callerApp == null) {
11404 throw new SecurityException(
11405 "Unable to find app for caller " + caller
11406 + " (pid=" + Binder.getCallingPid()
11407 + ") when binding service " + service);
11408 }
11409
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011410 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011411 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011412 activity = mMainStack.isInStackLocked(token);
11413 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011414 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011415 return 0;
11416 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011417 }
11418
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011419 int clientLabel = 0;
11420 PendingIntent clientIntent = null;
11421
11422 if (callerApp.info.uid == Process.SYSTEM_UID) {
11423 // Hacky kind of thing -- allow system stuff to tell us
11424 // what they are, so we can report this elsewhere for
11425 // others to know why certain services are running.
11426 try {
11427 clientIntent = (PendingIntent)service.getParcelableExtra(
11428 Intent.EXTRA_CLIENT_INTENT);
11429 } catch (RuntimeException e) {
11430 }
11431 if (clientIntent != null) {
11432 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11433 if (clientLabel != 0) {
11434 // There are no useful extras in the intent, trash them.
11435 // System code calling with this stuff just needs to know
11436 // this will happen.
11437 service = service.cloneFilter();
11438 }
11439 }
11440 }
11441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011442 ServiceLookupResult res =
11443 retrieveServiceLocked(service, resolvedType,
11444 Binder.getCallingPid(), Binder.getCallingUid());
11445 if (res == null) {
11446 return 0;
11447 }
11448 if (res.record == null) {
11449 return -1;
11450 }
11451 ServiceRecord s = res.record;
11452
11453 final long origId = Binder.clearCallingIdentity();
11454
11455 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011456 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011457 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011458 }
11459
11460 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11461 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011462 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011463
11464 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011465 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11466 if (clist == null) {
11467 clist = new ArrayList<ConnectionRecord>();
11468 s.connections.put(binder, clist);
11469 }
11470 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011471 b.connections.add(c);
11472 if (activity != null) {
11473 if (activity.connections == null) {
11474 activity.connections = new HashSet<ConnectionRecord>();
11475 }
11476 activity.connections.add(c);
11477 }
11478 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011479 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11480 b.client.hasAboveClient = true;
11481 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011482 clist = mServiceConnections.get(binder);
11483 if (clist == null) {
11484 clist = new ArrayList<ConnectionRecord>();
11485 mServiceConnections.put(binder, clist);
11486 }
11487 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011488
11489 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11490 s.lastActivity = SystemClock.uptimeMillis();
11491 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11492 return 0;
11493 }
11494 }
11495
11496 if (s.app != null) {
11497 // This could have made the service more important.
11498 updateOomAdjLocked(s.app);
11499 }
11500
Joe Onorato8a9b2202010-02-26 18:56:32 -080011501 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011502 + ": received=" + b.intent.received
11503 + " apps=" + b.intent.apps.size()
11504 + " doRebind=" + b.intent.doRebind);
11505
11506 if (s.app != null && b.intent.received) {
11507 // Service is already running, so we can immediately
11508 // publish the connection.
11509 try {
11510 c.conn.connected(s.name, b.intent.binder);
11511 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011512 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011513 + " to connection " + c.conn.asBinder()
11514 + " (in " + c.binding.client.processName + ")", e);
11515 }
11516
11517 // If this is the first app connected back to this binding,
11518 // and the service had previously asked to be told when
11519 // rebound, then do so.
11520 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11521 requestServiceBindingLocked(s, b.intent, true);
11522 }
11523 } else if (!b.intent.requested) {
11524 requestServiceBindingLocked(s, b.intent, false);
11525 }
11526
11527 Binder.restoreCallingIdentity(origId);
11528 }
11529
11530 return 1;
11531 }
11532
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011533 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011534 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011535 IBinder binder = c.conn.asBinder();
11536 AppBindRecord b = c.binding;
11537 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011538 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11539 if (clist != null) {
11540 clist.remove(c);
11541 if (clist.size() == 0) {
11542 s.connections.remove(binder);
11543 }
11544 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011545 b.connections.remove(c);
11546 if (c.activity != null && c.activity != skipAct) {
11547 if (c.activity.connections != null) {
11548 c.activity.connections.remove(c);
11549 }
11550 }
11551 if (b.client != skipApp) {
11552 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011553 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11554 b.client.updateHasAboveClientLocked();
11555 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011556 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011557 clist = mServiceConnections.get(binder);
11558 if (clist != null) {
11559 clist.remove(c);
11560 if (clist.size() == 0) {
11561 mServiceConnections.remove(binder);
11562 }
11563 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011564
11565 if (b.connections.size() == 0) {
11566 b.intent.apps.remove(b.client);
11567 }
11568
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011569 if (!c.serviceDead) {
11570 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
11571 + ": shouldUnbind=" + b.intent.hasBound);
11572 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11573 && b.intent.hasBound) {
11574 try {
11575 bumpServiceExecutingLocked(s, "unbind");
11576 updateOomAdjLocked(s.app);
11577 b.intent.hasBound = false;
11578 // Assume the client doesn't want to know about a rebind;
11579 // we will deal with that later if it asks for one.
11580 b.intent.doRebind = false;
11581 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11582 } catch (Exception e) {
11583 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
11584 serviceDoneExecutingLocked(s, true);
11585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011586 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011587
11588 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11589 bringDownServiceLocked(s, false);
11590 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011591 }
11592 }
11593
11594 public boolean unbindService(IServiceConnection connection) {
11595 synchronized (this) {
11596 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011597 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011598 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
11599 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011600 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011601 + connection.asBinder());
11602 return false;
11603 }
11604
11605 final long origId = Binder.clearCallingIdentity();
11606
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011607 while (clist.size() > 0) {
11608 ConnectionRecord r = clist.get(0);
11609 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011610
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011611 if (r.binding.service.app != null) {
11612 // This could have made the service less important.
11613 updateOomAdjLocked(r.binding.service.app);
11614 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011615 }
11616
11617 Binder.restoreCallingIdentity(origId);
11618 }
11619
11620 return true;
11621 }
11622
11623 public void publishService(IBinder token, Intent intent, IBinder service) {
11624 // Refuse possible leaked file descriptors
11625 if (intent != null && intent.hasFileDescriptors() == true) {
11626 throw new IllegalArgumentException("File descriptors passed in Intent");
11627 }
11628
11629 synchronized(this) {
11630 if (!(token instanceof ServiceRecord)) {
11631 throw new IllegalArgumentException("Invalid service token");
11632 }
11633 ServiceRecord r = (ServiceRecord)token;
11634
11635 final long origId = Binder.clearCallingIdentity();
11636
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011637 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011638 + " " + intent + ": " + service);
11639 if (r != null) {
11640 Intent.FilterComparison filter
11641 = new Intent.FilterComparison(intent);
11642 IntentBindRecord b = r.bindings.get(filter);
11643 if (b != null && !b.received) {
11644 b.binder = service;
11645 b.requested = true;
11646 b.received = true;
11647 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011648 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011649 = r.connections.values().iterator();
11650 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011651 ArrayList<ConnectionRecord> clist = it.next();
11652 for (int i=0; i<clist.size(); i++) {
11653 ConnectionRecord c = clist.get(i);
11654 if (!filter.equals(c.binding.intent.intent)) {
11655 if (DEBUG_SERVICE) Slog.v(
11656 TAG, "Not publishing to: " + c);
11657 if (DEBUG_SERVICE) Slog.v(
11658 TAG, "Bound intent: " + c.binding.intent.intent);
11659 if (DEBUG_SERVICE) Slog.v(
11660 TAG, "Published intent: " + intent);
11661 continue;
11662 }
11663 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
11664 try {
11665 c.conn.connected(r.name, service);
11666 } catch (Exception e) {
11667 Slog.w(TAG, "Failure sending service " + r.name +
11668 " to connection " + c.conn.asBinder() +
11669 " (in " + c.binding.client.processName + ")", e);
11670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011671 }
11672 }
11673 }
11674 }
11675
11676 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11677
11678 Binder.restoreCallingIdentity(origId);
11679 }
11680 }
11681 }
11682
11683 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11684 // Refuse possible leaked file descriptors
11685 if (intent != null && intent.hasFileDescriptors() == true) {
11686 throw new IllegalArgumentException("File descriptors passed in Intent");
11687 }
11688
11689 synchronized(this) {
11690 if (!(token instanceof ServiceRecord)) {
11691 throw new IllegalArgumentException("Invalid service token");
11692 }
11693 ServiceRecord r = (ServiceRecord)token;
11694
11695 final long origId = Binder.clearCallingIdentity();
11696
11697 if (r != null) {
11698 Intent.FilterComparison filter
11699 = new Intent.FilterComparison(intent);
11700 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011701 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011702 + " at " + b + ": apps="
11703 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011704
11705 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011706 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011707 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011708 // Applications have already bound since the last
11709 // unbind, so just rebind right here.
11710 requestServiceBindingLocked(r, b, true);
11711 } else {
11712 // Note to tell the service the next time there is
11713 // a new client.
11714 b.doRebind = true;
11715 }
11716 }
11717
Per Edelberg78f9fff2010-08-30 20:01:35 +020011718 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011719
11720 Binder.restoreCallingIdentity(origId);
11721 }
11722 }
11723 }
11724
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011725 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011726 synchronized(this) {
11727 if (!(token instanceof ServiceRecord)) {
11728 throw new IllegalArgumentException("Invalid service token");
11729 }
11730 ServiceRecord r = (ServiceRecord)token;
11731 boolean inStopping = mStoppingServices.contains(token);
11732 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011733 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011734 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011735 + " with incorrect token: given " + token
11736 + ", expected " + r);
11737 return;
11738 }
11739
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011740 if (type == 1) {
11741 // This is a call from a service start... take care of
11742 // book-keeping.
11743 r.callStart = true;
11744 switch (res) {
11745 case Service.START_STICKY_COMPATIBILITY:
11746 case Service.START_STICKY: {
11747 // We are done with the associated start arguments.
11748 r.findDeliveredStart(startId, true);
11749 // Don't stop if killed.
11750 r.stopIfKilled = false;
11751 break;
11752 }
11753 case Service.START_NOT_STICKY: {
11754 // We are done with the associated start arguments.
11755 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011756 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011757 // There is no more work, and this service
11758 // doesn't want to hang around if killed.
11759 r.stopIfKilled = true;
11760 }
11761 break;
11762 }
11763 case Service.START_REDELIVER_INTENT: {
11764 // We'll keep this item until they explicitly
11765 // call stop for it, but keep track of the fact
11766 // that it was delivered.
11767 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11768 if (si != null) {
11769 si.deliveryCount = 0;
11770 si.doneExecutingCount++;
11771 // Don't stop if killed.
11772 r.stopIfKilled = true;
11773 }
11774 break;
11775 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011776 case Service.START_TASK_REMOVED_COMPLETE: {
11777 // Special processing for onTaskRemoved(). Don't
11778 // impact normal onStartCommand() processing.
11779 r.findDeliveredStart(startId, true);
11780 break;
11781 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011782 default:
11783 throw new IllegalArgumentException(
11784 "Unknown service start result: " + res);
11785 }
11786 if (res == Service.START_STICKY_COMPATIBILITY) {
11787 r.callStart = false;
11788 }
11789 }
11790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011791 final long origId = Binder.clearCallingIdentity();
11792 serviceDoneExecutingLocked(r, inStopping);
11793 Binder.restoreCallingIdentity(origId);
11794 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011795 Slog.w(TAG, "Done executing unknown service from pid "
11796 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011797 }
11798 }
11799 }
11800
11801 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011802 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11803 + ": nesting=" + r.executeNesting
11804 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011805 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011806 r.executeNesting--;
11807 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011808 if (DEBUG_SERVICE) Slog.v(TAG,
11809 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011810 r.app.executingServices.remove(r);
11811 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011812 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11813 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011814 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11815 }
11816 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011817 if (DEBUG_SERVICE) Slog.v(TAG,
11818 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011819 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011820 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011821 }
11822 updateOomAdjLocked(r.app);
11823 }
11824 }
11825
11826 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011827 String anrMessage = null;
11828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011829 synchronized(this) {
11830 if (proc.executingServices.size() == 0 || proc.thread == null) {
11831 return;
11832 }
11833 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11834 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11835 ServiceRecord timeout = null;
11836 long nextTime = 0;
11837 while (it.hasNext()) {
11838 ServiceRecord sr = it.next();
11839 if (sr.executingStart < maxTime) {
11840 timeout = sr;
11841 break;
11842 }
11843 if (sr.executingStart > nextTime) {
11844 nextTime = sr.executingStart;
11845 }
11846 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011847 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011848 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011849 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011850 } else {
11851 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11852 msg.obj = proc;
11853 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11854 }
11855 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011856
11857 if (anrMessage != null) {
11858 appNotResponding(proc, null, null, anrMessage);
11859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011860 }
11861
11862 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011863 // BACKUP AND RESTORE
11864 // =========================================================
11865
11866 // Cause the target app to be launched if necessary and its backup agent
11867 // instantiated. The backup agent will invoke backupAgentCreated() on the
11868 // activity manager to announce its creation.
11869 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011870 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011871 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11872
11873 synchronized(this) {
11874 // !!! TODO: currently no check here that we're already bound
11875 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11876 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11877 synchronized (stats) {
11878 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11879 }
11880
Dianne Hackborne7f97212011-02-24 14:40:20 -080011881 // Backup agent is now in use, its package can't be stopped.
11882 try {
11883 AppGlobals.getPackageManager().setPackageStoppedState(
11884 app.packageName, false);
11885 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011886 } catch (IllegalArgumentException e) {
11887 Slog.w(TAG, "Failed trying to unstop package "
11888 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011889 }
11890
Christopher Tate181fafa2009-05-14 11:12:14 -070011891 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011892 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11893 ? new ComponentName(app.packageName, app.backupAgentName)
11894 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011895 // startProcessLocked() returns existing proc's record if it's already running
11896 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011897 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011898 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011899 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011900 return false;
11901 }
11902
11903 r.app = proc;
11904 mBackupTarget = r;
11905 mBackupAppName = app.packageName;
11906
Christopher Tate6fa95972009-06-05 18:43:55 -070011907 // Try not to kill the process during backup
11908 updateOomAdjLocked(proc);
11909
Christopher Tate181fafa2009-05-14 11:12:14 -070011910 // If the process is already attached, schedule the creation of the backup agent now.
11911 // If it is not yet live, this will be done when it attaches to the framework.
11912 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011913 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011914 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011915 proc.thread.scheduleCreateBackupAgent(app,
11916 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011917 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011918 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011919 }
11920 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011921 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011922 }
11923 // Invariants: at this point, the target app process exists and the application
11924 // is either already running or in the process of coming up. mBackupTarget and
11925 // mBackupAppName describe the app, so that when it binds back to the AM we
11926 // know that it's scheduled for a backup-agent operation.
11927 }
11928
11929 return true;
11930 }
11931
11932 // A backup agent has just come up
11933 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011934 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011935 + " = " + agent);
11936
11937 synchronized(this) {
11938 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011939 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011940 return;
11941 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011942 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011943
Dianne Hackborn06740692010-09-22 22:46:21 -070011944 long oldIdent = Binder.clearCallingIdentity();
11945 try {
11946 IBackupManager bm = IBackupManager.Stub.asInterface(
11947 ServiceManager.getService(Context.BACKUP_SERVICE));
11948 bm.agentConnected(agentPackageName, agent);
11949 } catch (RemoteException e) {
11950 // can't happen; the backup manager service is local
11951 } catch (Exception e) {
11952 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11953 e.printStackTrace();
11954 } finally {
11955 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011956 }
11957 }
11958
11959 // done with this agent
11960 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011961 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011962 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011963 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011964 return;
11965 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011966
11967 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011968 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011969 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011970 return;
11971 }
11972
Christopher Tate181fafa2009-05-14 11:12:14 -070011973 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011974 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011975 return;
11976 }
11977
Christopher Tate6fa95972009-06-05 18:43:55 -070011978 ProcessRecord proc = mBackupTarget.app;
11979 mBackupTarget = null;
11980 mBackupAppName = null;
11981
11982 // Not backing this app up any more; reset its OOM adjustment
11983 updateOomAdjLocked(proc);
11984
Christopher Tatec7b31e32009-06-10 15:49:30 -070011985 // If the app crashed during backup, 'thread' will be null here
11986 if (proc.thread != null) {
11987 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011988 proc.thread.scheduleDestroyBackupAgent(appInfo,
11989 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011990 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011991 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011992 e.printStackTrace();
11993 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011994 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011995 }
11996 }
11997 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011998 // BROADCASTS
11999 // =========================================================
12000
Josh Bartel7f208742010-02-25 11:01:44 -060012001 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012002 List cur) {
12003 final ContentResolver resolver = mContext.getContentResolver();
12004 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
12005 if (list == null) {
12006 return cur;
12007 }
12008 int N = list.size();
12009 for (int i=0; i<N; i++) {
12010 Intent intent = list.get(i);
12011 if (filter.match(resolver, intent, true, TAG) >= 0) {
12012 if (cur == null) {
12013 cur = new ArrayList<Intent>();
12014 }
12015 cur.add(intent);
12016 }
12017 }
12018 return cur;
12019 }
12020
12021 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012022 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012023 + mBroadcastsScheduled);
12024
12025 if (mBroadcastsScheduled) {
12026 return;
12027 }
12028 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
12029 mBroadcastsScheduled = true;
12030 }
12031
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012032 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012033 IIntentReceiver receiver, IntentFilter filter, String permission) {
12034 synchronized(this) {
12035 ProcessRecord callerApp = null;
12036 if (caller != null) {
12037 callerApp = getRecordForAppLocked(caller);
12038 if (callerApp == null) {
12039 throw new SecurityException(
12040 "Unable to find app for caller " + caller
12041 + " (pid=" + Binder.getCallingPid()
12042 + ") when registering receiver " + receiver);
12043 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012044 if (callerApp.info.uid != Process.SYSTEM_UID &&
12045 !callerApp.pkgList.contains(callerPackage)) {
12046 throw new SecurityException("Given caller package " + callerPackage
12047 + " is not running in process " + callerApp);
12048 }
12049 } else {
12050 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012051 }
12052
12053 List allSticky = null;
12054
12055 // Look for any matching sticky broadcasts...
12056 Iterator actions = filter.actionsIterator();
12057 if (actions != null) {
12058 while (actions.hasNext()) {
12059 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060012060 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012061 }
12062 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060012063 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012064 }
12065
12066 // The first sticky in the list is returned directly back to
12067 // the client.
12068 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12069
Joe Onorato8a9b2202010-02-26 18:56:32 -080012070 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012071 + ": " + sticky);
12072
12073 if (receiver == null) {
12074 return sticky;
12075 }
12076
12077 ReceiverList rl
12078 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12079 if (rl == null) {
12080 rl = new ReceiverList(this, callerApp,
12081 Binder.getCallingPid(),
12082 Binder.getCallingUid(), receiver);
12083 if (rl.app != null) {
12084 rl.app.receivers.add(rl);
12085 } else {
12086 try {
12087 receiver.asBinder().linkToDeath(rl, 0);
12088 } catch (RemoteException e) {
12089 return sticky;
12090 }
12091 rl.linkedToDeath = true;
12092 }
12093 mRegisteredReceivers.put(receiver.asBinder(), rl);
12094 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012095 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012096 rl.add(bf);
12097 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012098 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012099 }
12100 mReceiverResolver.addFilter(bf);
12101
12102 // Enqueue broadcasts for all existing stickies that match
12103 // this filter.
12104 if (allSticky != null) {
12105 ArrayList receivers = new ArrayList();
12106 receivers.add(bf);
12107
12108 int N = allSticky.size();
12109 for (int i=0; i<N; i++) {
12110 Intent intent = (Intent)allSticky.get(i);
12111 BroadcastRecord r = new BroadcastRecord(intent, null,
12112 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012113 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012114 if (mParallelBroadcasts.size() == 0) {
12115 scheduleBroadcastsLocked();
12116 }
12117 mParallelBroadcasts.add(r);
12118 }
12119 }
12120
12121 return sticky;
12122 }
12123 }
12124
12125 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012126 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012127
12128 boolean doNext = false;
12129
12130 synchronized(this) {
12131 ReceiverList rl
12132 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12133 if (rl != null) {
12134 if (rl.curBroadcast != null) {
12135 BroadcastRecord r = rl.curBroadcast;
12136 doNext = finishReceiverLocked(
12137 receiver.asBinder(), r.resultCode, r.resultData,
12138 r.resultExtras, r.resultAbort, true);
12139 }
12140
12141 if (rl.app != null) {
12142 rl.app.receivers.remove(rl);
12143 }
12144 removeReceiverLocked(rl);
12145 if (rl.linkedToDeath) {
12146 rl.linkedToDeath = false;
12147 rl.receiver.asBinder().unlinkToDeath(rl, 0);
12148 }
12149 }
12150 }
12151
12152 if (!doNext) {
12153 return;
12154 }
12155
12156 final long origId = Binder.clearCallingIdentity();
12157 processNextBroadcast(false);
12158 trimApplications();
12159 Binder.restoreCallingIdentity(origId);
12160 }
12161
12162 void removeReceiverLocked(ReceiverList rl) {
12163 mRegisteredReceivers.remove(rl.receiver.asBinder());
12164 int N = rl.size();
12165 for (int i=0; i<N; i++) {
12166 mReceiverResolver.removeFilter(rl.get(i));
12167 }
12168 }
12169
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012170 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12171 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12172 ProcessRecord r = mLruProcesses.get(i);
12173 if (r.thread != null) {
12174 try {
12175 r.thread.dispatchPackageBroadcast(cmd, packages);
12176 } catch (RemoteException ex) {
12177 }
12178 }
12179 }
12180 }
12181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012182 private final int broadcastIntentLocked(ProcessRecord callerApp,
12183 String callerPackage, Intent intent, String resolvedType,
12184 IIntentReceiver resultTo, int resultCode, String resultData,
12185 Bundle map, String requiredPermission,
12186 boolean ordered, boolean sticky, int callingPid, int callingUid) {
12187 intent = new Intent(intent);
12188
Dianne Hackborne7f97212011-02-24 14:40:20 -080012189 // By default broadcasts do not go to stopped apps.
12190 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12191
Joe Onorato8a9b2202010-02-26 18:56:32 -080012192 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012193 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
12194 + " ordered=" + ordered);
12195 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012196 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012197 }
12198
12199 // Handle special intents: if this broadcast is from the package
12200 // manager about a package being removed, we need to remove all of
12201 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012202 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012203 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012204 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12205 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012206 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012207 || uidRemoved) {
12208 if (checkComponentPermission(
12209 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012210 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012211 == PackageManager.PERMISSION_GRANTED) {
12212 if (uidRemoved) {
12213 final Bundle intentExtras = intent.getExtras();
12214 final int uid = intentExtras != null
12215 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12216 if (uid >= 0) {
12217 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12218 synchronized (bs) {
12219 bs.removeUidStatsLocked(uid);
12220 }
12221 }
12222 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012223 // If resources are unvailble just force stop all
12224 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012225 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012226 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12227 if (list != null && (list.length > 0)) {
12228 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070012229 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012230 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012231 sendPackageBroadcastLocked(
12232 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012233 }
12234 } else {
12235 Uri data = intent.getData();
12236 String ssp;
12237 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12238 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12239 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070012240 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070012241 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012242 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012243 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12244 new String[] {ssp});
12245 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012246 }
12247 }
12248 }
12249 } else {
12250 String msg = "Permission Denial: " + intent.getAction()
12251 + " broadcast from " + callerPackage + " (pid=" + callingPid
12252 + ", uid=" + callingUid + ")"
12253 + " requires "
12254 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012255 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012256 throw new SecurityException(msg);
12257 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012258
12259 // Special case for adding a package: by default turn on compatibility
12260 // mode.
12261 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070012262 Uri data = intent.getData();
12263 String ssp;
12264 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12265 mCompatModePackages.handlePackageAddedLocked(ssp,
12266 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012267 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012268 }
12269
12270 /*
12271 * If this is the time zone changed action, queue up a message that will reset the timezone
12272 * of all currently running processes. This message will get queued up before the broadcast
12273 * happens.
12274 */
12275 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12276 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12277 }
12278
Robert Greenwalt03595d02010-11-02 14:08:23 -070012279 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12280 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12281 }
12282
Robert Greenwalt434203a2010-10-11 16:00:27 -070012283 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12284 ProxyProperties proxy = intent.getParcelableExtra("proxy");
12285 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12286 }
12287
Dianne Hackborn854060af2009-07-09 18:14:31 -070012288 /*
12289 * Prevent non-system code (defined here to be non-persistent
12290 * processes) from sending protected broadcasts.
12291 */
12292 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12293 || callingUid == Process.SHELL_UID || callingUid == 0) {
12294 // Always okay.
12295 } else if (callerApp == null || !callerApp.persistent) {
12296 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012297 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070012298 intent.getAction())) {
12299 String msg = "Permission Denial: not allowed to send broadcast "
12300 + intent.getAction() + " from pid="
12301 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012302 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012303 throw new SecurityException(msg);
12304 }
12305 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012306 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012307 return BROADCAST_SUCCESS;
12308 }
12309 }
12310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012311 // Add to the sticky list if requested.
12312 if (sticky) {
12313 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12314 callingPid, callingUid)
12315 != PackageManager.PERMISSION_GRANTED) {
12316 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12317 + callingPid + ", uid=" + callingUid
12318 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012319 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012320 throw new SecurityException(msg);
12321 }
12322 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012323 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012324 + " and enforce permission " + requiredPermission);
12325 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12326 }
12327 if (intent.getComponent() != null) {
12328 throw new SecurityException(
12329 "Sticky broadcasts can't target a specific component");
12330 }
12331 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12332 if (list == null) {
12333 list = new ArrayList<Intent>();
12334 mStickyBroadcasts.put(intent.getAction(), list);
12335 }
12336 int N = list.size();
12337 int i;
12338 for (i=0; i<N; i++) {
12339 if (intent.filterEquals(list.get(i))) {
12340 // This sticky already exists, replace it.
12341 list.set(i, new Intent(intent));
12342 break;
12343 }
12344 }
12345 if (i >= N) {
12346 list.add(new Intent(intent));
12347 }
12348 }
12349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012350 // Figure out who all will receive this broadcast.
12351 List receivers = null;
12352 List<BroadcastFilter> registeredReceivers = null;
12353 try {
12354 if (intent.getComponent() != null) {
12355 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012356 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070012357 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012358 if (ai != null) {
12359 receivers = new ArrayList();
12360 ResolveInfo ri = new ResolveInfo();
12361 ri.activityInfo = ai;
12362 receivers.add(ri);
12363 }
12364 } else {
12365 // Need to resolve the intent to interested receivers...
12366 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12367 == 0) {
12368 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012369 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012370 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012371 }
Mihai Preda074edef2009-05-18 17:13:31 +020012372 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012373 }
12374 } catch (RemoteException ex) {
12375 // pm is in same process, this will never happen.
12376 }
12377
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012378 final boolean replacePending =
12379 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12380
Joe Onorato8a9b2202010-02-26 18:56:32 -080012381 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012382 + " replacePending=" + replacePending);
12383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012384 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12385 if (!ordered && NR > 0) {
12386 // If we are not serializing this broadcast, then send the
12387 // registered receivers separately so they don't wait for the
12388 // components to be launched.
12389 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12390 callerPackage, callingPid, callingUid, requiredPermission,
12391 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012392 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012393 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012394 TAG, "Enqueueing parallel broadcast " + r
12395 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012396 boolean replaced = false;
12397 if (replacePending) {
12398 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
12399 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012400 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012401 "***** DROPPING PARALLEL: " + intent);
12402 mParallelBroadcasts.set(i, r);
12403 replaced = true;
12404 break;
12405 }
12406 }
12407 }
12408 if (!replaced) {
12409 mParallelBroadcasts.add(r);
12410 scheduleBroadcastsLocked();
12411 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012412 registeredReceivers = null;
12413 NR = 0;
12414 }
12415
12416 // Merge into one list.
12417 int ir = 0;
12418 if (receivers != null) {
12419 // A special case for PACKAGE_ADDED: do not allow the package
12420 // being added to see this broadcast. This prevents them from
12421 // using this as a back door to get run as soon as they are
12422 // installed. Maybe in the future we want to have a special install
12423 // broadcast or such for apps, but we'd like to deliberately make
12424 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012425 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012426 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
12427 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
12428 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012429 Uri data = intent.getData();
12430 if (data != null) {
12431 String pkgName = data.getSchemeSpecificPart();
12432 if (pkgName != null) {
12433 skipPackages = new String[] { pkgName };
12434 }
12435 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012436 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012437 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070012438 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012439 if (skipPackages != null && (skipPackages.length > 0)) {
12440 for (String skipPackage : skipPackages) {
12441 if (skipPackage != null) {
12442 int NT = receivers.size();
12443 for (int it=0; it<NT; it++) {
12444 ResolveInfo curt = (ResolveInfo)receivers.get(it);
12445 if (curt.activityInfo.packageName.equals(skipPackage)) {
12446 receivers.remove(it);
12447 it--;
12448 NT--;
12449 }
12450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012451 }
12452 }
12453 }
12454
12455 int NT = receivers != null ? receivers.size() : 0;
12456 int it = 0;
12457 ResolveInfo curt = null;
12458 BroadcastFilter curr = null;
12459 while (it < NT && ir < NR) {
12460 if (curt == null) {
12461 curt = (ResolveInfo)receivers.get(it);
12462 }
12463 if (curr == null) {
12464 curr = registeredReceivers.get(ir);
12465 }
12466 if (curr.getPriority() >= curt.priority) {
12467 // Insert this broadcast record into the final list.
12468 receivers.add(it, curr);
12469 ir++;
12470 curr = null;
12471 it++;
12472 NT++;
12473 } else {
12474 // Skip to the next ResolveInfo in the final list.
12475 it++;
12476 curt = null;
12477 }
12478 }
12479 }
12480 while (ir < NR) {
12481 if (receivers == null) {
12482 receivers = new ArrayList();
12483 }
12484 receivers.add(registeredReceivers.get(ir));
12485 ir++;
12486 }
12487
12488 if ((receivers != null && receivers.size() > 0)
12489 || resultTo != null) {
12490 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12491 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012492 receivers, resultTo, resultCode, resultData, map, ordered,
12493 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012494 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012495 TAG, "Enqueueing ordered broadcast " + r
12496 + ": prev had " + mOrderedBroadcasts.size());
12497 if (DEBUG_BROADCAST) {
12498 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012499 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012500 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012501 boolean replaced = false;
12502 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012503 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012504 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012505 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012506 "***** DROPPING ORDERED: " + intent);
12507 mOrderedBroadcasts.set(i, r);
12508 replaced = true;
12509 break;
12510 }
12511 }
12512 }
12513 if (!replaced) {
12514 mOrderedBroadcasts.add(r);
12515 scheduleBroadcastsLocked();
12516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012517 }
12518
12519 return BROADCAST_SUCCESS;
12520 }
12521
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012522 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012523 // Refuse possible leaked file descriptors
12524 if (intent != null && intent.hasFileDescriptors() == true) {
12525 throw new IllegalArgumentException("File descriptors passed in Intent");
12526 }
12527
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012528 int flags = intent.getFlags();
12529
12530 if (!mProcessesReady) {
12531 // if the caller really truly claims to know what they're doing, go
12532 // ahead and allow the broadcast without launching any receivers
12533 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12534 intent = new Intent(intent);
12535 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12536 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12537 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12538 + " before boot completion");
12539 throw new IllegalStateException("Cannot broadcast before boot completed");
12540 }
12541 }
12542
12543 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12544 throw new IllegalArgumentException(
12545 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12546 }
12547
12548 return intent;
12549 }
12550
12551 public final int broadcastIntent(IApplicationThread caller,
12552 Intent intent, String resolvedType, IIntentReceiver resultTo,
12553 int resultCode, String resultData, Bundle map,
12554 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012555 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012556 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012558 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12559 final int callingPid = Binder.getCallingPid();
12560 final int callingUid = Binder.getCallingUid();
12561 final long origId = Binder.clearCallingIdentity();
12562 int res = broadcastIntentLocked(callerApp,
12563 callerApp != null ? callerApp.info.packageName : null,
12564 intent, resolvedType, resultTo,
12565 resultCode, resultData, map, requiredPermission, serialized,
12566 sticky, callingPid, callingUid);
12567 Binder.restoreCallingIdentity(origId);
12568 return res;
12569 }
12570 }
12571
12572 int broadcastIntentInPackage(String packageName, int uid,
12573 Intent intent, String resolvedType, IIntentReceiver resultTo,
12574 int resultCode, String resultData, Bundle map,
12575 String requiredPermission, boolean serialized, boolean sticky) {
12576 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012577 intent = verifyBroadcastLocked(intent);
12578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012579 final long origId = Binder.clearCallingIdentity();
12580 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12581 resultTo, resultCode, resultData, map, requiredPermission,
12582 serialized, sticky, -1, uid);
12583 Binder.restoreCallingIdentity(origId);
12584 return res;
12585 }
12586 }
12587
12588 public final void unbroadcastIntent(IApplicationThread caller,
12589 Intent intent) {
12590 // Refuse possible leaked file descriptors
12591 if (intent != null && intent.hasFileDescriptors() == true) {
12592 throw new IllegalArgumentException("File descriptors passed in Intent");
12593 }
12594
12595 synchronized(this) {
12596 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12597 != PackageManager.PERMISSION_GRANTED) {
12598 String msg = "Permission Denial: unbroadcastIntent() from pid="
12599 + Binder.getCallingPid()
12600 + ", uid=" + Binder.getCallingUid()
12601 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012602 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012603 throw new SecurityException(msg);
12604 }
12605 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12606 if (list != null) {
12607 int N = list.size();
12608 int i;
12609 for (i=0; i<N; i++) {
12610 if (intent.filterEquals(list.get(i))) {
12611 list.remove(i);
12612 break;
12613 }
12614 }
12615 }
12616 }
12617 }
12618
12619 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12620 String resultData, Bundle resultExtras, boolean resultAbort,
12621 boolean explicit) {
12622 if (mOrderedBroadcasts.size() == 0) {
12623 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012624 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012625 }
12626 return false;
12627 }
12628 BroadcastRecord r = mOrderedBroadcasts.get(0);
12629 if (r.receiver == null) {
12630 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012631 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012632 }
12633 return false;
12634 }
12635 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012636 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012637 return false;
12638 }
12639 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012640 r.state = BroadcastRecord.IDLE;
12641 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012642 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012643 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012644 }
12645 }
12646 r.receiver = null;
12647 r.intent.setComponent(null);
12648 if (r.curApp != null) {
12649 r.curApp.curReceiver = null;
12650 }
12651 if (r.curFilter != null) {
12652 r.curFilter.receiverList.curBroadcast = null;
12653 }
12654 r.curFilter = null;
12655 r.curApp = null;
12656 r.curComponent = null;
12657 r.curReceiver = null;
12658 mPendingBroadcast = null;
12659
12660 r.resultCode = resultCode;
12661 r.resultData = resultData;
12662 r.resultExtras = resultExtras;
12663 r.resultAbort = resultAbort;
12664
12665 // We will process the next receiver right now if this is finishing
12666 // an app receiver (which is always asynchronous) or after we have
12667 // come back from calling a receiver.
12668 return state == BroadcastRecord.APP_RECEIVE
12669 || state == BroadcastRecord.CALL_DONE_RECEIVE;
12670 }
12671
12672 public void finishReceiver(IBinder who, int resultCode, String resultData,
12673 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012674 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012675
12676 // Refuse possible leaked file descriptors
12677 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12678 throw new IllegalArgumentException("File descriptors passed in Bundle");
12679 }
12680
12681 boolean doNext;
12682
12683 final long origId = Binder.clearCallingIdentity();
12684
12685 synchronized(this) {
12686 doNext = finishReceiverLocked(
12687 who, resultCode, resultData, resultExtras, resultAbort, true);
12688 }
12689
12690 if (doNext) {
12691 processNextBroadcast(false);
12692 }
12693 trimApplications();
12694
12695 Binder.restoreCallingIdentity(origId);
12696 }
12697
Jeff Brown4d94a762010-09-23 11:33:28 -070012698 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012699 if (r.nextReceiver > 0) {
12700 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12701 if (curReceiver instanceof BroadcastFilter) {
12702 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012703 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012704 System.identityHashCode(r),
12705 r.intent.getAction(),
12706 r.nextReceiver - 1,
12707 System.identityHashCode(bf));
12708 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012709 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012710 System.identityHashCode(r),
12711 r.intent.getAction(),
12712 r.nextReceiver - 1,
12713 ((ResolveInfo)curReceiver).toString());
12714 }
12715 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012716 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012717 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012718 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012719 System.identityHashCode(r),
12720 r.intent.getAction(),
12721 r.nextReceiver,
12722 "NONE");
12723 }
12724 }
12725
Jeff Brown4d94a762010-09-23 11:33:28 -070012726 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12727 if (! mPendingBroadcastTimeoutMessage) {
12728 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12729 mHandler.sendMessageAtTime(msg, timeoutTime);
12730 mPendingBroadcastTimeoutMessage = true;
12731 }
12732 }
12733
12734 private final void cancelBroadcastTimeoutLocked() {
12735 if (mPendingBroadcastTimeoutMessage) {
12736 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12737 mPendingBroadcastTimeoutMessage = false;
12738 }
12739 }
12740
12741 private final void broadcastTimeoutLocked(boolean fromMsg) {
12742 if (fromMsg) {
12743 mPendingBroadcastTimeoutMessage = false;
12744 }
12745
12746 if (mOrderedBroadcasts.size() == 0) {
12747 return;
12748 }
12749
12750 long now = SystemClock.uptimeMillis();
12751 BroadcastRecord r = mOrderedBroadcasts.get(0);
12752 if (fromMsg) {
12753 if (mDidDexOpt) {
12754 // Delay timeouts until dexopt finishes.
12755 mDidDexOpt = false;
12756 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12757 setBroadcastTimeoutLocked(timeoutTime);
12758 return;
12759 }
12760 if (! mProcessesReady) {
12761 // Only process broadcast timeouts if the system is ready. That way
12762 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12763 // to do heavy lifting for system up.
12764 return;
12765 }
12766
12767 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12768 if (timeoutTime > now) {
12769 // We can observe premature timeouts because we do not cancel and reset the
12770 // broadcast timeout message after each receiver finishes. Instead, we set up
12771 // an initial timeout then kick it down the road a little further as needed
12772 // when it expires.
12773 if (DEBUG_BROADCAST) Slog.v(TAG,
12774 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12775 + timeoutTime);
12776 setBroadcastTimeoutLocked(timeoutTime);
12777 return;
12778 }
12779 }
12780
12781 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12782 + ", started " + (now - r.receiverTime) + "ms ago");
12783 r.receiverTime = now;
12784 r.anrCount++;
12785
12786 // Current receiver has passed its expiration date.
12787 if (r.nextReceiver <= 0) {
12788 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12789 return;
12790 }
12791
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012792 ProcessRecord app = null;
12793 String anrMessage = null;
12794
Jeff Brown4d94a762010-09-23 11:33:28 -070012795 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12796 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12797 logBroadcastReceiverDiscardLocked(r);
12798 if (curReceiver instanceof BroadcastFilter) {
12799 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12800 if (bf.receiverList.pid != 0
12801 && bf.receiverList.pid != MY_PID) {
12802 synchronized (this.mPidsSelfLocked) {
12803 app = this.mPidsSelfLocked.get(
12804 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012805 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012806 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012807 } else {
12808 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012809 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012810
Jeff Brown4d94a762010-09-23 11:33:28 -070012811 if (app != null) {
12812 anrMessage = "Broadcast of " + r.intent.toString();
12813 }
12814
12815 if (mPendingBroadcast == r) {
12816 mPendingBroadcast = null;
12817 }
12818
12819 // Move on to the next receiver.
12820 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12821 r.resultExtras, r.resultAbort, true);
12822 scheduleBroadcastsLocked();
12823
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012824 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012825 // Post the ANR to the handler since we do not want to process ANRs while
12826 // potentially holding our lock.
12827 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012829 }
12830
12831 private final void processCurBroadcastLocked(BroadcastRecord r,
12832 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012833 if (DEBUG_BROADCAST) Slog.v(TAG,
12834 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012835 if (app.thread == null) {
12836 throw new RemoteException();
12837 }
12838 r.receiver = app.thread.asBinder();
12839 r.curApp = app;
12840 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012841 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012842
12843 // Tell the application to launch this receiver.
12844 r.intent.setComponent(r.curComponent);
12845
12846 boolean started = false;
12847 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012848 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012849 "Delivering to component " + r.curComponent
12850 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012851 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012852 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012853 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012854 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012855 if (DEBUG_BROADCAST) Slog.v(TAG,
12856 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012857 started = true;
12858 } finally {
12859 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012860 if (DEBUG_BROADCAST) Slog.v(TAG,
12861 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012862 r.receiver = null;
12863 r.curApp = null;
12864 app.curReceiver = null;
12865 }
12866 }
12867
12868 }
12869
Jeff Brown4d94a762010-09-23 11:33:28 -070012870 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012871 Intent intent, int resultCode, String data, Bundle extras,
12872 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012873 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012874 if (app != null && app.thread != null) {
12875 // If we have an app thread, do the call through that so it is
12876 // correctly ordered with other one-way calls.
12877 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012878 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012879 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012880 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012881 }
12882 }
12883
Jeff Brown4d94a762010-09-23 11:33:28 -070012884 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012885 BroadcastFilter filter, boolean ordered) {
12886 boolean skip = false;
12887 if (filter.requiredPermission != null) {
12888 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012889 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012890 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012891 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012892 + r.intent.toString()
12893 + " from " + r.callerPackage + " (pid="
12894 + r.callingPid + ", uid=" + r.callingUid + ")"
12895 + " requires " + filter.requiredPermission
12896 + " due to registered receiver " + filter);
12897 skip = true;
12898 }
12899 }
12900 if (r.requiredPermission != null) {
12901 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012902 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012903 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012904 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012905 + r.intent.toString()
12906 + " to " + filter.receiverList.app
12907 + " (pid=" + filter.receiverList.pid
12908 + ", uid=" + filter.receiverList.uid + ")"
12909 + " requires " + r.requiredPermission
12910 + " due to sender " + r.callerPackage
12911 + " (uid " + r.callingUid + ")");
12912 skip = true;
12913 }
12914 }
12915
12916 if (!skip) {
12917 // If this is not being sent as an ordered broadcast, then we
12918 // don't want to touch the fields that keep track of the current
12919 // state of ordered broadcasts.
12920 if (ordered) {
12921 r.receiver = filter.receiverList.receiver.asBinder();
12922 r.curFilter = filter;
12923 filter.receiverList.curBroadcast = r;
12924 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012925 if (filter.receiverList.app != null) {
12926 // Bump hosting application to no longer be in background
12927 // scheduling class. Note that we can't do that if there
12928 // isn't an app... but we can only be in that case for
12929 // things that directly call the IActivityManager API, which
12930 // are already core system stuff so don't matter for this.
12931 r.curApp = filter.receiverList.app;
12932 filter.receiverList.app.curReceiver = r;
12933 updateOomAdjLocked();
12934 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012935 }
12936 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012937 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012938 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012939 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012940 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012941 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012942 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012943 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012944 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012945 if (ordered) {
12946 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12947 }
12948 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012949 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012950 if (ordered) {
12951 r.receiver = null;
12952 r.curFilter = null;
12953 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012954 if (filter.receiverList.app != null) {
12955 filter.receiverList.app.curReceiver = null;
12956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012957 }
12958 }
12959 }
12960 }
12961
Dianne Hackborn12527f92009-11-11 17:39:50 -080012962 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12963 if (r.callingUid < 0) {
12964 // This was from a registerReceiver() call; ignore it.
12965 return;
12966 }
12967 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12968 MAX_BROADCAST_HISTORY-1);
12969 r.finishTime = SystemClock.uptimeMillis();
12970 mBroadcastHistory[0] = r;
12971 }
12972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012973 private final void processNextBroadcast(boolean fromMsg) {
12974 synchronized(this) {
12975 BroadcastRecord r;
12976
Joe Onorato8a9b2202010-02-26 18:56:32 -080012977 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012978 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012979 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012980
12981 updateCpuStats();
12982
12983 if (fromMsg) {
12984 mBroadcastsScheduled = false;
12985 }
12986
12987 // First, deliver any non-serialized broadcasts right away.
12988 while (mParallelBroadcasts.size() > 0) {
12989 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012990 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012991 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012992 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012993 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012994 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012995 for (int i=0; i<N; i++) {
12996 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012997 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012998 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012999 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070013000 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013001 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080013002 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013003 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013004 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013005 }
13006
13007 // Now take care of the next serialized one...
13008
13009 // If we are waiting for a process to come up to handle the next
13010 // broadcast, then do nothing at this point. Just in case, we
13011 // check that the process we're waiting for still exists.
13012 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070013013 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013014 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070013015 + mPendingBroadcast.curApp);
13016 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013017
13018 boolean isDead;
13019 synchronized (mPidsSelfLocked) {
13020 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
13021 }
13022 if (!isDead) {
13023 // It's still alive, so keep waiting
13024 return;
13025 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013026 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013027 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013028 mPendingBroadcast.state = BroadcastRecord.IDLE;
13029 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013030 mPendingBroadcast = null;
13031 }
13032 }
13033
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013034 boolean looped = false;
13035
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013036 do {
13037 if (mOrderedBroadcasts.size() == 0) {
13038 // No more broadcasts pending, so all done!
13039 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013040 if (looped) {
13041 // If we had finished the last ordered broadcast, then
13042 // make sure all processes have correct oom and sched
13043 // adjustments.
13044 updateOomAdjLocked();
13045 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013046 return;
13047 }
13048 r = mOrderedBroadcasts.get(0);
13049 boolean forceReceive = false;
13050
13051 // Ensure that even if something goes awry with the timeout
13052 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050013053 // and continue to make progress.
13054 //
13055 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070013056 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050013057 // one time heavy lifting after system upgrades and can take
13058 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013059 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013060 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050013061 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013062 if ((numReceivers > 0) &&
13063 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013064 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013065 + " now=" + now
13066 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080013067 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013068 + " intent=" + r.intent
13069 + " numReceivers=" + numReceivers
13070 + " nextReceiver=" + r.nextReceiver
13071 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070013072 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013073 forceReceive = true;
13074 r.state = BroadcastRecord.IDLE;
13075 }
13076 }
13077
13078 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013079 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013080 "processNextBroadcast() called when not idle (state="
13081 + r.state + ")");
13082 return;
13083 }
13084
13085 if (r.receivers == null || r.nextReceiver >= numReceivers
13086 || r.resultAbort || forceReceive) {
13087 // No more receivers for this broadcast! Send the final
13088 // result if requested...
13089 if (r.resultTo != null) {
13090 try {
13091 if (DEBUG_BROADCAST) {
13092 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013093 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013094 + " seq=" + seq + " app=" + r.callerApp);
13095 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013096 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013097 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013098 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020013099 // Set this to null so that the reference
13100 // (local and remote) isnt kept in the mBroadcastHistory.
13101 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013102 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013103 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013104 }
13105 }
13106
Joe Onorato8a9b2202010-02-26 18:56:32 -080013107 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070013108 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013109
Joe Onorato8a9b2202010-02-26 18:56:32 -080013110 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013111 + r);
13112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013113 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080013114 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013115 mOrderedBroadcasts.remove(0);
13116 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013117 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013118 continue;
13119 }
13120 } while (r == null);
13121
13122 // Get the next receiver...
13123 int recIdx = r.nextReceiver++;
13124
13125 // Keep track of when this receiver started, and make sure there
13126 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080013127 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013128 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080013129 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070013130 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013131 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013132 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070013133 }
13134 if (! mPendingBroadcastTimeoutMessage) {
13135 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013136 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070013137 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
13138 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013139 }
13140
13141 Object nextReceiver = r.receivers.get(recIdx);
13142 if (nextReceiver instanceof BroadcastFilter) {
13143 // Simple case: this is a registered receiver who gets
13144 // a direct call.
13145 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013146 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013147 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013148 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070013149 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013150 if (r.receiver == null || !r.ordered) {
13151 // The receiver has already finished, so schedule to
13152 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013153 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
13154 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013155 r.state = BroadcastRecord.IDLE;
13156 scheduleBroadcastsLocked();
13157 }
13158 return;
13159 }
13160
13161 // Hard case: need to instantiate the receiver, possibly
13162 // starting its application process to host it.
13163
13164 ResolveInfo info =
13165 (ResolveInfo)nextReceiver;
13166
13167 boolean skip = false;
13168 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013169 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
13170 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013171 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013172 if (!info.activityInfo.exported) {
13173 Slog.w(TAG, "Permission Denial: broadcasting "
13174 + r.intent.toString()
13175 + " from " + r.callerPackage + " (pid=" + r.callingPid
13176 + ", uid=" + r.callingUid + ")"
13177 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
13178 + " due to receiver " + info.activityInfo.packageName
13179 + "/" + info.activityInfo.name);
13180 } else {
13181 Slog.w(TAG, "Permission Denial: broadcasting "
13182 + r.intent.toString()
13183 + " from " + r.callerPackage + " (pid=" + r.callingPid
13184 + ", uid=" + r.callingUid + ")"
13185 + " requires " + info.activityInfo.permission
13186 + " due to receiver " + info.activityInfo.packageName
13187 + "/" + info.activityInfo.name);
13188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013189 skip = true;
13190 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070013191 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013192 r.requiredPermission != null) {
13193 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013194 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013195 checkPermission(r.requiredPermission,
13196 info.activityInfo.applicationInfo.packageName);
13197 } catch (RemoteException e) {
13198 perm = PackageManager.PERMISSION_DENIED;
13199 }
13200 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013201 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013202 + r.intent + " to "
13203 + info.activityInfo.applicationInfo.packageName
13204 + " requires " + r.requiredPermission
13205 + " due to sender " + r.callerPackage
13206 + " (uid " + r.callingUid + ")");
13207 skip = true;
13208 }
13209 }
13210 if (r.curApp != null && r.curApp.crashing) {
13211 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013212 if (DEBUG_BROADCAST) Slog.v(TAG,
13213 "Skipping deliver ordered " + r + " to " + r.curApp
13214 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013215 skip = true;
13216 }
13217
13218 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013219 if (DEBUG_BROADCAST) Slog.v(TAG,
13220 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013221 r.receiver = null;
13222 r.curFilter = null;
13223 r.state = BroadcastRecord.IDLE;
13224 scheduleBroadcastsLocked();
13225 return;
13226 }
13227
13228 r.state = BroadcastRecord.APP_RECEIVE;
13229 String targetProcess = info.activityInfo.processName;
13230 r.curComponent = new ComponentName(
13231 info.activityInfo.applicationInfo.packageName,
13232 info.activityInfo.name);
13233 r.curReceiver = info.activityInfo;
13234
Dianne Hackborne7f97212011-02-24 14:40:20 -080013235 // Broadcast is being executed, its package can't be stopped.
13236 try {
13237 AppGlobals.getPackageManager().setPackageStoppedState(
13238 r.curComponent.getPackageName(), false);
13239 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080013240 } catch (IllegalArgumentException e) {
13241 Slog.w(TAG, "Failed trying to unstop package "
13242 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080013243 }
13244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013245 // Is this receiver's application already running?
13246 ProcessRecord app = getProcessRecordLocked(targetProcess,
13247 info.activityInfo.applicationInfo.uid);
13248 if (app != null && app.thread != null) {
13249 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070013250 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013251 processCurBroadcastLocked(r, app);
13252 return;
13253 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013254 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013255 + r.curComponent, e);
13256 }
13257
13258 // If a dead object exception was thrown -- fall through to
13259 // restart the application.
13260 }
13261
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013262 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013263 if (DEBUG_BROADCAST) Slog.v(TAG,
13264 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013265 if ((r.curApp=startProcessLocked(targetProcess,
13266 info.activityInfo.applicationInfo, true,
13267 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013268 "broadcast", r.curComponent,
13269 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
13270 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013271 // Ah, this recipient is unavailable. Finish it if necessary,
13272 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013273 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013274 + info.activityInfo.applicationInfo.packageName + "/"
13275 + info.activityInfo.applicationInfo.uid + " for broadcast "
13276 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070013277 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013278 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
13279 r.resultExtras, r.resultAbort, true);
13280 scheduleBroadcastsLocked();
13281 r.state = BroadcastRecord.IDLE;
13282 return;
13283 }
13284
13285 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013286 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013287 }
13288 }
13289
13290 // =========================================================
13291 // INSTRUMENTATION
13292 // =========================================================
13293
13294 public boolean startInstrumentation(ComponentName className,
13295 String profileFile, int flags, Bundle arguments,
13296 IInstrumentationWatcher watcher) {
13297 // Refuse possible leaked file descriptors
13298 if (arguments != null && arguments.hasFileDescriptors()) {
13299 throw new IllegalArgumentException("File descriptors passed in Bundle");
13300 }
13301
13302 synchronized(this) {
13303 InstrumentationInfo ii = null;
13304 ApplicationInfo ai = null;
13305 try {
13306 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013307 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013308 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013309 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013310 } catch (PackageManager.NameNotFoundException e) {
13311 }
13312 if (ii == null) {
13313 reportStartInstrumentationFailure(watcher, className,
13314 "Unable to find instrumentation info for: " + className);
13315 return false;
13316 }
13317 if (ai == null) {
13318 reportStartInstrumentationFailure(watcher, className,
13319 "Unable to find instrumentation target package: " + ii.targetPackage);
13320 return false;
13321 }
13322
13323 int match = mContext.getPackageManager().checkSignatures(
13324 ii.targetPackage, ii.packageName);
13325 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13326 String msg = "Permission Denial: starting instrumentation "
13327 + className + " from pid="
13328 + Binder.getCallingPid()
13329 + ", uid=" + Binder.getCallingPid()
13330 + " not allowed because package " + ii.packageName
13331 + " does not have a signature matching the target "
13332 + ii.targetPackage;
13333 reportStartInstrumentationFailure(watcher, className, msg);
13334 throw new SecurityException(msg);
13335 }
13336
13337 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070013338 // Instrumentation can kill and relaunch even persistent processes
13339 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013340 ProcessRecord app = addAppLocked(ai);
13341 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013342 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013343 app.instrumentationProfileFile = profileFile;
13344 app.instrumentationArguments = arguments;
13345 app.instrumentationWatcher = watcher;
13346 app.instrumentationResultClass = className;
13347 Binder.restoreCallingIdentity(origId);
13348 }
13349
13350 return true;
13351 }
13352
13353 /**
13354 * Report errors that occur while attempting to start Instrumentation. Always writes the
13355 * error to the logs, but if somebody is watching, send the report there too. This enables
13356 * the "am" command to report errors with more information.
13357 *
13358 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
13359 * @param cn The component name of the instrumentation.
13360 * @param report The error report.
13361 */
13362 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13363 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013364 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013365 try {
13366 if (watcher != null) {
13367 Bundle results = new Bundle();
13368 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13369 results.putString("Error", report);
13370 watcher.instrumentationStatus(cn, -1, results);
13371 }
13372 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013373 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013374 }
13375 }
13376
13377 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13378 if (app.instrumentationWatcher != null) {
13379 try {
13380 // NOTE: IInstrumentationWatcher *must* be oneway here
13381 app.instrumentationWatcher.instrumentationFinished(
13382 app.instrumentationClass,
13383 resultCode,
13384 results);
13385 } catch (RemoteException e) {
13386 }
13387 }
13388 app.instrumentationWatcher = null;
13389 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013390 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013391 app.instrumentationProfileFile = null;
13392 app.instrumentationArguments = null;
13393
Christopher Tate3dacd842011-08-19 14:56:15 -070013394 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013395 }
13396
13397 public void finishInstrumentation(IApplicationThread target,
13398 int resultCode, Bundle results) {
13399 // Refuse possible leaked file descriptors
13400 if (results != null && results.hasFileDescriptors()) {
13401 throw new IllegalArgumentException("File descriptors passed in Intent");
13402 }
13403
13404 synchronized(this) {
13405 ProcessRecord app = getRecordForAppLocked(target);
13406 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013407 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013408 return;
13409 }
13410 final long origId = Binder.clearCallingIdentity();
13411 finishInstrumentationLocked(app, resultCode, results);
13412 Binder.restoreCallingIdentity(origId);
13413 }
13414 }
13415
13416 // =========================================================
13417 // CONFIGURATION
13418 // =========================================================
13419
13420 public ConfigurationInfo getDeviceConfigurationInfo() {
13421 ConfigurationInfo config = new ConfigurationInfo();
13422 synchronized (this) {
13423 config.reqTouchScreen = mConfiguration.touchscreen;
13424 config.reqKeyboardType = mConfiguration.keyboard;
13425 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013426 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13427 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013428 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13429 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013430 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13431 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013432 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13433 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070013434 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013435 }
13436 return config;
13437 }
13438
13439 public Configuration getConfiguration() {
13440 Configuration ci;
13441 synchronized(this) {
13442 ci = new Configuration(mConfiguration);
13443 }
13444 return ci;
13445 }
13446
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013447 public void updatePersistentConfiguration(Configuration values) {
13448 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13449 "updateConfiguration()");
13450 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13451 "updateConfiguration()");
13452 if (values == null) {
13453 throw new NullPointerException("Configuration must not be null");
13454 }
13455
13456 synchronized(this) {
13457 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013458 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013459 Binder.restoreCallingIdentity(origId);
13460 }
13461 }
13462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013463 public void updateConfiguration(Configuration values) {
13464 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13465 "updateConfiguration()");
13466
13467 synchronized(this) {
13468 if (values == null && mWindowManager != null) {
13469 // sentinel: fetch the current configuration from the window manager
13470 values = mWindowManager.computeNewConfiguration();
13471 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013472
13473 if (mWindowManager != null) {
13474 mProcessList.applyDisplaySize(mWindowManager);
13475 }
13476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013477 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013478 if (values != null) {
13479 Settings.System.clearConfiguration(values);
13480 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013481 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013482 Binder.restoreCallingIdentity(origId);
13483 }
13484 }
13485
13486 /**
13487 * Do either or both things: (1) change the current configuration, and (2)
13488 * make sure the given activity is running with the (now) current
13489 * configuration. Returns true if the activity has been left running, or
13490 * false if <var>starting</var> is being destroyed to match the new
13491 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013492 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013493 */
13494 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013495 ActivityRecord starting, boolean persistent, boolean initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013496 int changes = 0;
13497
13498 boolean kept = true;
13499
13500 if (values != null) {
13501 Configuration newConfig = new Configuration(mConfiguration);
13502 changes = newConfig.updateFrom(values);
13503 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013504 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013505 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013506 }
13507
Doug Zongker2bec3d42009-12-04 12:52:44 -080013508 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013509
Dianne Hackborn813075a62011-11-14 17:45:19 -080013510 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013511 saveLocaleLocked(values.locale,
13512 !values.locale.equals(mConfiguration.locale),
13513 values.userSetLocale);
13514 }
13515
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013516 mConfigurationSeq++;
13517 if (mConfigurationSeq <= 0) {
13518 mConfigurationSeq = 1;
13519 }
13520 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013521 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013522 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013523
13524 final Configuration configCopy = new Configuration(mConfiguration);
13525
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013526 AttributeCache ac = AttributeCache.instance();
13527 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013528 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013530
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013531 // Make sure all resources in our process are updated
13532 // right now, so that anyone who is going to retrieve
13533 // resource values after we return will be sure to get
13534 // the new ones. This is especially important during
13535 // boot, where the first config change needs to guarantee
13536 // all resources have that config before following boot
13537 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080013538 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013539
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013540 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013541 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013542 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013543 mHandler.sendMessage(msg);
13544 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013545
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013546 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13547 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013548 try {
13549 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013550 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013551 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013552 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013553 }
13554 } catch (Exception e) {
13555 }
13556 }
13557 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013558 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13559 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013560 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13561 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013562 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13563 broadcastIntentLocked(null, null,
13564 new Intent(Intent.ACTION_LOCALE_CHANGED),
13565 null, null, 0, null, null,
13566 null, false, false, MY_PID, Process.SYSTEM_UID);
13567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013568 }
13569 }
13570
13571 if (changes != 0 && starting == null) {
13572 // If the configuration changed, and the caller is not already
13573 // in the process of starting an activity, then find the top
13574 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013575 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013576 }
13577
13578 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013579 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013580 // And we need to make sure at this point that all other activities
13581 // are made visible with the correct configuration.
13582 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013583 }
13584
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013585 if (values != null && mWindowManager != null) {
13586 mWindowManager.setNewConfiguration(mConfiguration);
13587 }
13588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013589 return kept;
13590 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013591
13592 /**
13593 * Save the locale. You must be inside a synchronized (this) block.
13594 */
13595 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13596 if(isDiff) {
13597 SystemProperties.set("user.language", l.getLanguage());
13598 SystemProperties.set("user.region", l.getCountry());
13599 }
13600
13601 if(isPersist) {
13602 SystemProperties.set("persist.sys.language", l.getLanguage());
13603 SystemProperties.set("persist.sys.country", l.getCountry());
13604 SystemProperties.set("persist.sys.localevar", l.getVariant());
13605 }
13606 }
13607
13608 // =========================================================
13609 // LIFETIME MANAGEMENT
13610 // =========================================================
13611
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013612 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013613 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013614 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013615 // This adjustment has already been computed. If we are calling
13616 // from the top, we may have already computed our adjustment with
13617 // an earlier hidden adjustment that isn't really for us... if
13618 // so, use the new hidden adjustment.
13619 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013620 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013621 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013622 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013623 }
13624
13625 if (app.thread == null) {
13626 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013627 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013628 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013629 }
13630
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013631 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13632 app.adjSource = null;
13633 app.adjTarget = null;
13634 app.empty = false;
13635 app.hidden = false;
13636
13637 final int activitiesSize = app.activities.size();
13638
Dianne Hackborn7d608422011-08-07 16:24:18 -070013639 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013640 // The max adjustment doesn't allow this app to be anything
13641 // below foreground, so it is not worth doing work for it.
13642 app.adjType = "fixed";
13643 app.adjSeq = mAdjSeq;
13644 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013645 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013646 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013647 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013648 // System process can do UI, and when they do we want to have
13649 // them trim their memory after the user leaves the UI. To
13650 // facilitate this, here we need to determine whether or not it
13651 // is currently showing UI.
13652 app.systemNoUi = true;
13653 if (app == TOP_APP) {
13654 app.systemNoUi = false;
13655 } else if (activitiesSize > 0) {
13656 for (int j = 0; j < activitiesSize; j++) {
13657 final ActivityRecord r = app.activities.get(j);
13658 if (r.visible) {
13659 app.systemNoUi = false;
13660 break;
13661 }
13662 }
13663 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013664 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013665 }
13666
13667 final boolean hadForegroundActivities = app.foregroundActivities;
13668
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013669 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013670 app.keeping = false;
13671 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013672
The Android Open Source Project4df24232009-03-05 14:34:35 -080013673 // Determine the importance of the process, starting with most
13674 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013675 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013676 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013677 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013678 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013679 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013680 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013681 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013682 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013683 } else if (app.instrumentationClass != null) {
13684 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013685 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013686 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013687 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013688 } else if (app.curReceiver != null ||
13689 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13690 // An app that is currently receiving a broadcast also
13691 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013692 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013693 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013694 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013695 } else if (app.executingServices.size() > 0) {
13696 // An app that is currently executing a service callback also
13697 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013698 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013699 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013700 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013701 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013702 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013703 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013704 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013705 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013706 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013707 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013708 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013709 // A very not-needed process. If this is lower in the lru list,
13710 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013711 adj = hiddenAdj;
13712 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013713 app.hidden = true;
13714 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013715 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013716 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013717
13718 // Examine all activities if not already foreground.
13719 if (!app.foregroundActivities && activitiesSize > 0) {
13720 for (int j = 0; j < activitiesSize; j++) {
13721 final ActivityRecord r = app.activities.get(j);
13722 if (r.visible) {
13723 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013724 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13725 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013726 app.adjType = "visible";
13727 }
13728 schedGroup = Process.THREAD_GROUP_DEFAULT;
13729 app.hidden = false;
13730 app.foregroundActivities = true;
13731 break;
13732 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13733 || r.state == ActivityState.STOPPING) {
13734 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013735 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13736 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013737 app.adjType = "stopping";
13738 }
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -080013739 app.hidden = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013740 app.foregroundActivities = true;
13741 }
13742 }
13743 }
13744
Dianne Hackborn7d608422011-08-07 16:24:18 -070013745 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013746 if (app.foregroundServices) {
13747 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013748 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013749 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013750 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013751 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013752 } else if (app.forcingToForeground != null) {
13753 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013754 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013755 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013756 app.adjType = "force-foreground";
13757 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013758 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013759 }
13760 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013761
Dianne Hackborn7d608422011-08-07 16:24:18 -070013762 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013763 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013764 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013765 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013766 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013767 app.adjType = "heavy";
13768 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013769
Dianne Hackborn7d608422011-08-07 16:24:18 -070013770 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013771 // This process is hosting what we currently consider to be the
13772 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013773 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013774 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013775 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013776 app.adjType = "home";
13777 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013778
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013779 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13780 && app.activities.size() > 0) {
13781 // This was the previous process that showed UI to the user.
13782 // We want to try to keep it around more aggressively, to give
13783 // a good experience around switching between two apps.
13784 adj = ProcessList.PREVIOUS_APP_ADJ;
13785 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13786 app.hidden = false;
13787 app.adjType = "previous";
13788 }
13789
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013790 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13791 + " reason=" + app.adjType);
13792
The Android Open Source Project4df24232009-03-05 14:34:35 -080013793 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013794 // there are applications dependent on our services or providers, but
13795 // this gives us a baseline and makes sure we don't get into an
13796 // infinite recursion.
13797 app.adjSeq = mAdjSeq;
13798 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013799
Christopher Tate6fa95972009-06-05 18:43:55 -070013800 if (mBackupTarget != null && app == mBackupTarget.app) {
13801 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013802 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013803 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013804 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013805 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013806 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013807 }
13808 }
13809
Dianne Hackborn7d608422011-08-07 16:24:18 -070013810 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013811 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013812 final long now = SystemClock.uptimeMillis();
13813 // This process is more important if the top activity is
13814 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013815 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013816 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013817 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013818 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013819 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013820 // If this process has shown some UI, let it immediately
13821 // go to the LRU list because it may be pretty heavy with
13822 // UI stuff. We'll tag it with a label just to help
13823 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013824 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013825 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013826 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013827 } else {
13828 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13829 // This service has seen some activity within
13830 // recent memory, so we will keep its process ahead
13831 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013832 if (adj > ProcessList.SERVICE_ADJ) {
13833 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013834 app.adjType = "started-services";
13835 app.hidden = false;
13836 }
13837 }
13838 // If we have let the service slide into the background
13839 // state, still have some text describing what it is doing
13840 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013841 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013842 app.adjType = "started-bg-services";
13843 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013844 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013845 // Don't kill this process because it is doing work; it
13846 // has said it is doing work.
13847 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013848 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013849 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013850 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013851 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013852 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013853 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013854 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013855 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013856 // XXX should compute this based on the max of
13857 // all connected clients.
13858 ConnectionRecord cr = clist.get(i);
13859 if (cr.binding.client == app) {
13860 // Binding to ourself is not interesting.
13861 continue;
13862 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013863 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013864 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013865 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013866 int myHiddenAdj = hiddenAdj;
13867 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013868 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013869 myHiddenAdj = client.hiddenAdj;
13870 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013871 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013872 }
13873 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013874 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013875 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013876 String adjType = null;
13877 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13878 // Not doing bind OOM management, so treat
13879 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013880 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013881 // If this process has shown some UI, let it immediately
13882 // go to the LRU list because it may be pretty heavy with
13883 // UI stuff. We'll tag it with a label just to help
13884 // debug and understand what is going on.
13885 if (adj > clientAdj) {
13886 adjType = "bound-bg-ui-services";
13887 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013888 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013889 clientAdj = adj;
13890 } else {
13891 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13892 // This service has not seen activity within
13893 // recent memory, so allow it to drop to the
13894 // LRU list if there is no other reason to keep
13895 // it around. We'll also tag it with a label just
13896 // to help debug and undertand what is going on.
13897 if (adj > clientAdj) {
13898 adjType = "bound-bg-services";
13899 }
13900 clientAdj = adj;
13901 }
13902 }
13903 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013904 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013905 // If this process has recently shown UI, and
13906 // the process that is binding to it is less
13907 // important than being visible, then we don't
13908 // care about the binding as much as we care
13909 // about letting this process get into the LRU
13910 // list to be killed and restarted if needed for
13911 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013912 if (app.hasShownUi && app != mHomeProcess
13913 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013914 adjType = "bound-bg-ui-services";
13915 } else {
13916 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13917 |Context.BIND_IMPORTANT)) != 0) {
13918 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013919 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13920 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13921 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13922 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13923 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013924 adj = clientAdj;
13925 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013926 app.pendingUiClean = true;
13927 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13928 adj = ProcessList.VISIBLE_APP_ADJ;
13929 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013930 }
13931 if (!client.hidden) {
13932 app.hidden = false;
13933 }
13934 if (client.keeping) {
13935 app.keeping = true;
13936 }
13937 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013938 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013939 }
13940 if (adjType != null) {
13941 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013942 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13943 .REASON_SERVICE_IN_USE;
13944 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013945 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013946 app.adjTarget = s.name;
13947 }
13948 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13949 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13950 schedGroup = Process.THREAD_GROUP_DEFAULT;
13951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013952 }
13953 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013954 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13955 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013956 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013957 (a.visible || a.state == ActivityState.RESUMED
13958 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013959 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013960 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13961 schedGroup = Process.THREAD_GROUP_DEFAULT;
13962 }
13963 app.hidden = false;
13964 app.adjType = "service";
13965 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13966 .REASON_SERVICE_IN_USE;
13967 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013968 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013969 app.adjTarget = s.name;
13970 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013971 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013972 }
13973 }
13974 }
13975 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013976
Dianne Hackborn287952c2010-09-22 22:34:31 -070013977 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013978 // would like to avoid killing it unless it would prevent the current
13979 // application from running. By default we put the process in
13980 // with the rest of the background processes; as we scan through
13981 // its services we may bump it up from there.
13982 if (adj > hiddenAdj) {
13983 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013984 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013985 app.adjType = "bg-services";
13986 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013987 }
13988
Dianne Hackborn7d608422011-08-07 16:24:18 -070013989 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013990 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013991 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013992 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013993 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013994 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013995 if (cpr.clients.size() != 0) {
13996 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013997 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013998 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013999 if (client == app) {
14000 // Being our own client is not interesting.
14001 continue;
14002 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014003 int myHiddenAdj = hiddenAdj;
14004 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014005 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014006 myHiddenAdj = client.hiddenAdj;
14007 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014008 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014009 }
14010 }
14011 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014012 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014013 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014014 if (app.hasShownUi && app != mHomeProcess
14015 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014016 app.adjType = "bg-ui-provider";
14017 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014018 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14019 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014020 app.adjType = "provider";
14021 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014022 if (!client.hidden) {
14023 app.hidden = false;
14024 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014025 if (client.keeping) {
14026 app.keeping = true;
14027 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070014028 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14029 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014030 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014031 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014032 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014033 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014034 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14035 schedGroup = Process.THREAD_GROUP_DEFAULT;
14036 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014037 }
14038 }
14039 // If the provider has external (non-framework) process
14040 // dependencies, ensure that its adjustment is at least
14041 // FOREGROUND_APP_ADJ.
14042 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014043 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14044 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014045 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014046 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014047 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014048 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014049 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014050 }
14051 }
14052 }
14053 }
14054
14055 app.curRawAdj = adj;
14056
Joe Onorato8a9b2202010-02-26 18:56:32 -080014057 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014058 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14059 if (adj > app.maxAdj) {
14060 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014061 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014062 schedGroup = Process.THREAD_GROUP_DEFAULT;
14063 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014064 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014065 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014066 app.keeping = true;
14067 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014068
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014069 if (app.hasAboveClient) {
14070 // If this process has bound to any services with BIND_ABOVE_CLIENT,
14071 // then we need to drop its adjustment to be lower than the service's
14072 // in order to honor the request. We want to drop it by one adjustment
14073 // level... but there is special meaning applied to various levels so
14074 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014075 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014076 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070014077 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14078 adj = ProcessList.VISIBLE_APP_ADJ;
14079 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14080 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14081 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14082 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014083 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014084 adj++;
14085 }
14086 }
14087
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014088 if (adj == ProcessList.SERVICE_ADJ) {
14089 if (doingAll) {
14090 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14091 mNewNumServiceProcs++;
14092 }
14093 if (app.serviceb) {
14094 adj = ProcessList.SERVICE_B_ADJ;
14095 }
14096 } else {
14097 app.serviceb = false;
14098 }
14099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014100 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014101 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014102
14103 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070014104 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
14105 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014106 }
14107
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014108 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014109 }
14110
14111 /**
14112 * Ask a given process to GC right now.
14113 */
14114 final void performAppGcLocked(ProcessRecord app) {
14115 try {
14116 app.lastRequestedGc = SystemClock.uptimeMillis();
14117 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014118 if (app.reportLowMemory) {
14119 app.reportLowMemory = false;
14120 app.thread.scheduleLowMemory();
14121 } else {
14122 app.thread.processInBackground();
14123 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014124 }
14125 } catch (Exception e) {
14126 // whatever.
14127 }
14128 }
14129
14130 /**
14131 * Returns true if things are idle enough to perform GCs.
14132 */
Josh Bartel7f208742010-02-25 11:01:44 -060014133 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014134 return mParallelBroadcasts.size() == 0
14135 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014136 && (mSleeping || (mMainStack.mResumedActivity != null &&
14137 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014138 }
14139
14140 /**
14141 * Perform GCs on all processes that are waiting for it, but only
14142 * if things are idle.
14143 */
14144 final void performAppGcsLocked() {
14145 final int N = mProcessesToGc.size();
14146 if (N <= 0) {
14147 return;
14148 }
Josh Bartel7f208742010-02-25 11:01:44 -060014149 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014150 while (mProcessesToGc.size() > 0) {
14151 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014152 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014153 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14154 <= SystemClock.uptimeMillis()) {
14155 // To avoid spamming the system, we will GC processes one
14156 // at a time, waiting a few seconds between each.
14157 performAppGcLocked(proc);
14158 scheduleAppGcsLocked();
14159 return;
14160 } else {
14161 // It hasn't been long enough since we last GCed this
14162 // process... put it in the list to wait for its time.
14163 addProcessToGcListLocked(proc);
14164 break;
14165 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014166 }
14167 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014168
14169 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014170 }
14171 }
14172
14173 /**
14174 * If all looks good, perform GCs on all processes waiting for them.
14175 */
14176 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060014177 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014178 performAppGcsLocked();
14179 return;
14180 }
14181 // Still not idle, wait some more.
14182 scheduleAppGcsLocked();
14183 }
14184
14185 /**
14186 * Schedule the execution of all pending app GCs.
14187 */
14188 final void scheduleAppGcsLocked() {
14189 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014190
14191 if (mProcessesToGc.size() > 0) {
14192 // Schedule a GC for the time to the next process.
14193 ProcessRecord proc = mProcessesToGc.get(0);
14194 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14195
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014196 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014197 long now = SystemClock.uptimeMillis();
14198 if (when < (now+GC_TIMEOUT)) {
14199 when = now + GC_TIMEOUT;
14200 }
14201 mHandler.sendMessageAtTime(msg, when);
14202 }
14203 }
14204
14205 /**
14206 * Add a process to the array of processes waiting to be GCed. Keeps the
14207 * list in sorted order by the last GC time. The process can't already be
14208 * on the list.
14209 */
14210 final void addProcessToGcListLocked(ProcessRecord proc) {
14211 boolean added = false;
14212 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14213 if (mProcessesToGc.get(i).lastRequestedGc <
14214 proc.lastRequestedGc) {
14215 added = true;
14216 mProcessesToGc.add(i+1, proc);
14217 break;
14218 }
14219 }
14220 if (!added) {
14221 mProcessesToGc.add(0, proc);
14222 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014223 }
14224
14225 /**
14226 * Set up to ask a process to GC itself. This will either do it
14227 * immediately, or put it on the list of processes to gc the next
14228 * time things are idle.
14229 */
14230 final void scheduleAppGcLocked(ProcessRecord app) {
14231 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014232 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014233 return;
14234 }
14235 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014236 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014237 scheduleAppGcsLocked();
14238 }
14239 }
14240
Dianne Hackborn287952c2010-09-22 22:34:31 -070014241 final void checkExcessivePowerUsageLocked(boolean doKills) {
14242 updateCpuStatsNow();
14243
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014244 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014245 boolean doWakeKills = doKills;
14246 boolean doCpuKills = doKills;
14247 if (mLastPowerCheckRealtime == 0) {
14248 doWakeKills = false;
14249 }
14250 if (mLastPowerCheckUptime == 0) {
14251 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014252 }
14253 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014254 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014255 }
14256 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014257 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14258 final long curUptime = SystemClock.uptimeMillis();
14259 final long uptimeSince = curUptime - mLastPowerCheckUptime;
14260 mLastPowerCheckRealtime = curRealtime;
14261 mLastPowerCheckUptime = curUptime;
14262 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14263 doWakeKills = false;
14264 }
14265 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14266 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014267 }
14268 int i = mLruProcesses.size();
14269 while (i > 0) {
14270 i--;
14271 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014272 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014273 long wtime;
14274 synchronized (stats) {
14275 wtime = stats.getProcessWakeTime(app.info.uid,
14276 app.pid, curRealtime);
14277 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014278 long wtimeUsed = wtime - app.lastWakeTime;
14279 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14280 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014281 StringBuilder sb = new StringBuilder(128);
14282 sb.append("Wake for ");
14283 app.toShortString(sb);
14284 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014285 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014286 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014287 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014288 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014289 sb.append((wtimeUsed*100)/realtimeSince);
14290 sb.append("%)");
14291 Slog.i(TAG, sb.toString());
14292 sb.setLength(0);
14293 sb.append("CPU for ");
14294 app.toShortString(sb);
14295 sb.append(": over ");
14296 TimeUtils.formatDuration(uptimeSince, sb);
14297 sb.append(" used ");
14298 TimeUtils.formatDuration(cputimeUsed, sb);
14299 sb.append(" (");
14300 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014301 sb.append("%)");
14302 Slog.i(TAG, sb.toString());
14303 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014304 // If a process has held a wake lock for more
14305 // than 50% of the time during this period,
14306 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070014307 if (doWakeKills && realtimeSince > 0
14308 && ((wtimeUsed*100)/realtimeSince) >= 50) {
14309 synchronized (stats) {
14310 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14311 realtimeSince, wtimeUsed);
14312 }
14313 Slog.w(TAG, "Excessive wake lock in " + app.processName
14314 + " (pid " + app.pid + "): held " + wtimeUsed
14315 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014316 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14317 app.processName, app.setAdj, "excessive wake lock");
14318 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014319 } else if (doCpuKills && uptimeSince > 0
14320 && ((cputimeUsed*100)/uptimeSince) >= 50) {
14321 synchronized (stats) {
14322 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14323 uptimeSince, cputimeUsed);
14324 }
14325 Slog.w(TAG, "Excessive CPU in " + app.processName
14326 + " (pid " + app.pid + "): used " + cputimeUsed
14327 + " during " + uptimeSince);
14328 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14329 app.processName, app.setAdj, "excessive cpu");
14330 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014331 } else {
14332 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014333 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014334 }
14335 }
14336 }
14337 }
14338
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014339 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014340 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014341 app.hiddenAdj = hiddenAdj;
14342
14343 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014344 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014345 }
14346
Dianne Hackborn287952c2010-09-22 22:34:31 -070014347 final boolean wasKeeping = app.keeping;
14348
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014349 boolean success = true;
14350
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014351 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014352
Jeff Brown10e89712011-07-08 18:52:57 -070014353 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070014354 if (false) {
14355 // Removing for now. Forcing GCs is not so useful anymore
14356 // with Dalvik, and the new memory level hint facility is
14357 // better for what we need to do these days.
14358 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
14359 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14360 // If this app is transitioning from foreground to
14361 // non-foreground, have it do a gc.
14362 scheduleAppGcLocked(app);
14363 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14364 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14365 // Likewise do a gc when an app is moving in to the
14366 // background (such as a service stopping).
14367 scheduleAppGcLocked(app);
14368 }
Jeff Brown10e89712011-07-08 18:52:57 -070014369 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014370
Jeff Brown10e89712011-07-08 18:52:57 -070014371 if (wasKeeping && !app.keeping) {
14372 // This app is no longer something we want to keep. Note
14373 // its current wake lock time to later know to kill it if
14374 // it is not behaving well.
14375 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14376 synchronized (stats) {
14377 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14378 app.pid, SystemClock.elapsedRealtime());
14379 }
14380 app.lastCpuTime = app.curCpuTime;
14381 }
14382
14383 app.setRawAdj = app.curRawAdj;
14384 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014385
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014386 if (app.curAdj != app.setAdj) {
14387 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackbornbbb09ac2011-11-30 11:31:29 -080014388 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014389 TAG, "Set " + app.pid + " " + app.processName +
14390 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014391 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070014392 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014393 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014394 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070014395 }
14396 }
14397 if (app.setSchedGroup != app.curSchedGroup) {
14398 app.setSchedGroup = app.curSchedGroup;
14399 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14400 "Setting process group of " + app.processName
14401 + " to " + app.curSchedGroup);
14402 if (app.waitingToKill != null &&
14403 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14404 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14405 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14406 app.processName, app.setAdj, app.waitingToKill);
14407 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014408 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070014409 } else {
14410 if (true) {
14411 long oldId = Binder.clearCallingIdentity();
14412 try {
14413 Process.setProcessGroup(app.pid, app.curSchedGroup);
14414 } catch (Exception e) {
14415 Slog.w(TAG, "Failed setting process group of " + app.pid
14416 + " to " + app.curSchedGroup);
14417 e.printStackTrace();
14418 } finally {
14419 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014420 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014421 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070014422 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014423 try {
Jeff Brown10e89712011-07-08 18:52:57 -070014424 app.thread.setSchedulingGroup(app.curSchedGroup);
14425 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014426 }
14427 }
14428 }
14429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014430 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014431 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014432 }
14433
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014434 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014435 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014436 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014437 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014438 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014439 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014440 }
14441 }
14442 return resumedActivity;
14443 }
14444
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014445 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014446 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014447 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14448 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014449 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14450 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014451
14452 mAdjSeq++;
14453
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014454 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014455 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14456 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014457 if (nowHidden != wasHidden) {
14458 // Changed to/from hidden state, so apps after it in the LRU
14459 // list may also be changed.
14460 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014461 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014462 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014463 }
14464
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014465 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014466 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014467 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14468
14469 if (false) {
14470 RuntimeException e = new RuntimeException();
14471 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014472 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014473 }
14474
14475 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014476 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014477
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014478 // Let's determine how many processes we have running vs.
14479 // how many slots we have for background processes; we may want
14480 // to put multiple processes in a slot of there are enough of
14481 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014482 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014483 int factor = (mLruProcesses.size()-4)/numSlots;
14484 if (factor < 1) factor = 1;
14485 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014486 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014487
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014488 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014489 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014490 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014491 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014492 while (i > 0) {
14493 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014494 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080014495 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014496 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14497 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014498 && app.curAdj == curHiddenAdj) {
14499 step++;
14500 if (step >= factor) {
14501 step = 0;
14502 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014503 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014504 }
14505 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014506 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014507 numHidden++;
14508 if (numHidden > mProcessLimit) {
14509 Slog.i(TAG, "No longer want " + app.processName
14510 + " (pid " + app.pid + "): hidden #" + numHidden);
14511 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14512 app.processName, app.setAdj, "too many background");
14513 app.killedBackground = true;
14514 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070014515 }
14516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014517 }
14518 }
14519
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014520 mNumServiceProcs = mNewNumServiceProcs;
14521
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014522 // Now determine the memory trimming level of background processes.
14523 // Unfortunately we need to start at the back of the list to do this
14524 // properly. We only do this if the number of background apps we
14525 // are managing to keep around is less than half the maximum we desire;
14526 // if we are keeping a good number around, we'll let them use whatever
14527 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014528 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014529 final int N = mLruProcesses.size();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014530 factor = numHidden/3;
14531 int minFactor = 2;
14532 if (mHomeProcess != null) minFactor++;
14533 if (mPreviousProcess != null) minFactor++;
14534 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014535 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014536 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014537 for (i=0; i<N; i++) {
14538 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014539 if (app.curAdj >= ProcessList.HOME_APP_ADJ
14540 && app.curAdj != ProcessList.SERVICE_B_ADJ
14541 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014542 if (app.trimMemoryLevel < curLevel && app.thread != null) {
14543 try {
14544 app.thread.scheduleTrimMemory(curLevel);
14545 } catch (RemoteException e) {
14546 }
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080014547 if (false) {
14548 // For now we won't do this; our memory trimming seems
14549 // to be good enough at this point that destroying
14550 // activities causes more harm than good.
14551 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14552 && app != mHomeProcess && app != mPreviousProcess) {
14553 // For these apps we will also finish their activities
14554 // to help them free memory.
14555 mMainStack.destroyActivitiesLocked(app, false, "trim");
14556 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014557 }
14558 }
14559 app.trimMemoryLevel = curLevel;
14560 step++;
14561 if (step >= factor) {
14562 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014563 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14564 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014565 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014566 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14567 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014568 break;
14569 }
14570 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014571 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014572 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014573 && app.thread != null) {
14574 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014575 app.thread.scheduleTrimMemory(
14576 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014577 } catch (RemoteException e) {
14578 }
14579 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014580 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014581 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014582 && app.pendingUiClean) {
14583 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14584 && app.thread != null) {
14585 try {
14586 app.thread.scheduleTrimMemory(
14587 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14588 } catch (RemoteException e) {
14589 }
14590 }
14591 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14592 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014593 } else {
14594 app.trimMemoryLevel = 0;
14595 }
14596 }
14597 } else {
14598 final int N = mLruProcesses.size();
14599 for (i=0; i<N; i++) {
14600 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014601 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014602 && app.pendingUiClean) {
14603 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14604 && app.thread != null) {
14605 try {
14606 app.thread.scheduleTrimMemory(
14607 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14608 } catch (RemoteException e) {
14609 }
14610 }
14611 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14612 app.pendingUiClean = false;
14613 } else {
14614 app.trimMemoryLevel = 0;
14615 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014616 }
14617 }
14618
14619 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070014620 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014622 }
14623
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014624 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014625 synchronized (this) {
14626 int i;
14627
14628 // First remove any unused application processes whose package
14629 // has been removed.
14630 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14631 final ProcessRecord app = mRemovedProcesses.get(i);
14632 if (app.activities.size() == 0
14633 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014634 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014635 TAG, "Exiting empty application process "
14636 + app.processName + " ("
14637 + (app.thread != null ? app.thread.asBinder() : null)
14638 + ")\n");
14639 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070014640 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14641 app.processName, app.setAdj, "empty");
14642 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014643 } else {
14644 try {
14645 app.thread.scheduleExit();
14646 } catch (Exception e) {
14647 // Ignore exceptions.
14648 }
14649 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014650 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014651 mRemovedProcesses.remove(i);
14652
14653 if (app.persistent) {
14654 if (app.persistent) {
14655 addAppLocked(app.info);
14656 }
14657 }
14658 }
14659 }
14660
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014661 // Now update the oom adj for all processes.
14662 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014663 }
14664 }
14665
14666 /** This method sends the specified signal to each of the persistent apps */
14667 public void signalPersistentProcesses(int sig) throws RemoteException {
14668 if (sig != Process.SIGNAL_USR1) {
14669 throw new SecurityException("Only SIGNAL_USR1 is allowed");
14670 }
14671
14672 synchronized (this) {
14673 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14674 != PackageManager.PERMISSION_GRANTED) {
14675 throw new SecurityException("Requires permission "
14676 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14677 }
14678
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014679 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14680 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014681 if (r.thread != null && r.persistent) {
14682 Process.sendSignal(r.pid, sig);
14683 }
14684 }
14685 }
14686 }
14687
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014688 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14689 if (proc == null || proc == mProfileProc) {
14690 proc = mProfileProc;
14691 path = mProfileFile;
14692 profileType = mProfileType;
14693 clearProfilerLocked();
14694 }
14695 if (proc == null) {
14696 return;
14697 }
14698 try {
14699 proc.thread.profilerControl(false, path, null, profileType);
14700 } catch (RemoteException e) {
14701 throw new IllegalStateException("Process disappeared");
14702 }
14703 }
14704
14705 private void clearProfilerLocked() {
14706 if (mProfileFd != null) {
14707 try {
14708 mProfileFd.close();
14709 } catch (IOException e) {
14710 }
14711 }
14712 mProfileApp = null;
14713 mProfileProc = null;
14714 mProfileFile = null;
14715 mProfileType = 0;
14716 mAutoStopProfiler = false;
14717 }
14718
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014719 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014720 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014721
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014722 try {
14723 synchronized (this) {
14724 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14725 // its own permission.
14726 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14727 != PackageManager.PERMISSION_GRANTED) {
14728 throw new SecurityException("Requires permission "
14729 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014730 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014731
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014732 if (start && fd == null) {
14733 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014734 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014735
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014736 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014737 if (process != null) {
14738 try {
14739 int pid = Integer.parseInt(process);
14740 synchronized (mPidsSelfLocked) {
14741 proc = mPidsSelfLocked.get(pid);
14742 }
14743 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014744 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014745
14746 if (proc == null) {
14747 HashMap<String, SparseArray<ProcessRecord>> all
14748 = mProcessNames.getMap();
14749 SparseArray<ProcessRecord> procs = all.get(process);
14750 if (procs != null && procs.size() > 0) {
14751 proc = procs.valueAt(0);
14752 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014753 }
14754 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014755
14756 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014757 throw new IllegalArgumentException("Unknown process: " + process);
14758 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014759
14760 if (start) {
14761 stopProfilerLocked(null, null, 0);
14762 setProfileApp(proc.info, proc.processName, path, fd, false);
14763 mProfileProc = proc;
14764 mProfileType = profileType;
14765 try {
14766 fd = fd.dup();
14767 } catch (IOException e) {
14768 fd = null;
14769 }
14770 proc.thread.profilerControl(start, path, fd, profileType);
14771 fd = null;
14772 mProfileFd = null;
14773 } else {
14774 stopProfilerLocked(proc, path, profileType);
14775 if (fd != null) {
14776 try {
14777 fd.close();
14778 } catch (IOException e) {
14779 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014780 }
14781 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014782
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014783 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014784 }
14785 } catch (RemoteException e) {
14786 throw new IllegalStateException("Process disappeared");
14787 } finally {
14788 if (fd != null) {
14789 try {
14790 fd.close();
14791 } catch (IOException e) {
14792 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014793 }
14794 }
14795 }
Andy McFadden824c5102010-07-09 16:26:57 -070014796
14797 public boolean dumpHeap(String process, boolean managed,
14798 String path, ParcelFileDescriptor fd) throws RemoteException {
14799
14800 try {
14801 synchronized (this) {
14802 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14803 // its own permission (same as profileControl).
14804 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14805 != PackageManager.PERMISSION_GRANTED) {
14806 throw new SecurityException("Requires permission "
14807 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14808 }
14809
14810 if (fd == null) {
14811 throw new IllegalArgumentException("null fd");
14812 }
14813
14814 ProcessRecord proc = null;
14815 try {
14816 int pid = Integer.parseInt(process);
14817 synchronized (mPidsSelfLocked) {
14818 proc = mPidsSelfLocked.get(pid);
14819 }
14820 } catch (NumberFormatException e) {
14821 }
14822
14823 if (proc == null) {
14824 HashMap<String, SparseArray<ProcessRecord>> all
14825 = mProcessNames.getMap();
14826 SparseArray<ProcessRecord> procs = all.get(process);
14827 if (procs != null && procs.size() > 0) {
14828 proc = procs.valueAt(0);
14829 }
14830 }
14831
14832 if (proc == null || proc.thread == null) {
14833 throw new IllegalArgumentException("Unknown process: " + process);
14834 }
14835
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014836 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14837 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014838 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14839 throw new SecurityException("Process not debuggable: " + proc);
14840 }
14841 }
14842
14843 proc.thread.dumpHeap(managed, path, fd);
14844 fd = null;
14845 return true;
14846 }
14847 } catch (RemoteException e) {
14848 throw new IllegalStateException("Process disappeared");
14849 } finally {
14850 if (fd != null) {
14851 try {
14852 fd.close();
14853 } catch (IOException e) {
14854 }
14855 }
14856 }
14857 }
14858
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014859 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14860 public void monitor() {
14861 synchronized (this) { }
14862 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014863
14864 public void onCoreSettingsChange(Bundle settings) {
14865 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14866 ProcessRecord processRecord = mLruProcesses.get(i);
14867 try {
14868 if (processRecord.thread != null) {
14869 processRecord.thread.setCoreSettings(settings);
14870 }
14871 } catch (RemoteException re) {
14872 /* ignore */
14873 }
14874 }
14875 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014876
14877 // Multi-user methods
14878
14879 public boolean switchUser(int userid) {
14880 // TODO
14881 return true;
14882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014883}