blob: 367844dde0260c08c4d5e4834dafbea64c7cc9b8 [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;
417
418 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400419 * Packages that the user has asked to have run in screen size
420 * compatibility mode instead of filling the screen.
421 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700422 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400423
424 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 * Set of PendingResultRecord objects that are currently active.
426 */
427 final HashSet mPendingResultRecords = new HashSet();
428
429 /**
430 * Set of IntentSenderRecord objects that are currently active.
431 */
432 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
433 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
434
435 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800436 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700437 * already logged DropBox entries for. Guarded by itself. If
438 * something (rogue user app) forces this over
439 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
440 */
441 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
442 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
443
444 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700445 * Strict Mode background batched logging state.
446 *
447 * The string buffer is guarded by itself, and its lock is also
448 * used to determine if another batched write is already
449 * in-flight.
450 */
451 private final StringBuilder mStrictModeBuffer = new StringBuilder();
452
453 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700454 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
455 */
456 private boolean mPendingBroadcastTimeoutMessage;
457
458 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 * Intent broadcast that we have tried to start, but are
460 * waiting for its application's process to be created. We only
461 * need one (instead of a list) because we always process broadcasts
462 * one at a time, so no others can be started while waiting for this
463 * one.
464 */
465 BroadcastRecord mPendingBroadcast = null;
466
467 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700468 * The receiver index that is pending, to restart the broadcast if needed.
469 */
470 int mPendingBroadcastRecvIndex;
471
472 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 * Keeps track of all IIntentReceivers that have been registered for
474 * broadcasts. Hash keys are the receiver IBinder, hash value is
475 * a ReceiverList.
476 */
477 final HashMap mRegisteredReceivers = new HashMap();
478
479 /**
480 * Resolver for broadcast intents to registered receivers.
481 * Holds BroadcastFilter (subclass of IntentFilter).
482 */
483 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
484 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
485 @Override
486 protected boolean allowFilterResult(
487 BroadcastFilter filter, List<BroadcastFilter> dest) {
488 IBinder target = filter.receiverList.receiver.asBinder();
489 for (int i=dest.size()-1; i>=0; i--) {
490 if (dest.get(i).receiverList.receiver.asBinder() == target) {
491 return false;
492 }
493 }
494 return true;
495 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700496
497 @Override
498 protected String packageForFilter(BroadcastFilter filter) {
499 return filter.packageName;
500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 };
502
503 /**
504 * State of all active sticky broadcasts. Keys are the action of the
505 * sticky Intent, values are an ArrayList of all broadcasted intents with
506 * that action (which should usually be one).
507 */
508 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
509 new HashMap<String, ArrayList<Intent>>();
510
511 /**
512 * All currently running services.
513 */
514 final HashMap<ComponentName, ServiceRecord> mServices =
515 new HashMap<ComponentName, ServiceRecord>();
516
517 /**
518 * All currently running services indexed by the Intent used to start them.
519 */
520 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
521 new HashMap<Intent.FilterComparison, ServiceRecord>();
522
523 /**
524 * All currently bound service connections. Keys are the IBinder of
525 * the client's IServiceConnection.
526 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700527 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
528 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529
530 /**
531 * List of services that we have been asked to start,
532 * but haven't yet been able to. It is used to hold start requests
533 * while waiting for their corresponding application thread to get
534 * going.
535 */
536 final ArrayList<ServiceRecord> mPendingServices
537 = new ArrayList<ServiceRecord>();
538
539 /**
540 * List of services that are scheduled to restart following a crash.
541 */
542 final ArrayList<ServiceRecord> mRestartingServices
543 = new ArrayList<ServiceRecord>();
544
545 /**
546 * List of services that are in the process of being stopped.
547 */
548 final ArrayList<ServiceRecord> mStoppingServices
549 = new ArrayList<ServiceRecord>();
550
551 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700552 * Backup/restore process management
553 */
554 String mBackupAppName = null;
555 BackupRecord mBackupTarget = null;
556
557 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 * List of PendingThumbnailsRecord objects of clients who are still
559 * waiting to receive all of the thumbnails for a task.
560 */
561 final ArrayList mPendingThumbnails = new ArrayList();
562
563 /**
564 * List of HistoryRecord objects that have been finished and must
565 * still report back to a pending thumbnail receiver.
566 */
567 final ArrayList mCancelledThumbnails = new ArrayList();
568
569 /**
570 * All of the currently running global content providers. Keys are a
571 * string containing the provider name and values are a
572 * ContentProviderRecord object containing the data about it. Note
573 * that a single provider may be published under multiple names, so
574 * there may be multiple entries here for a single one in mProvidersByClass.
575 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700576 final HashMap<String, ContentProviderRecord> mProvidersByName
577 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578
579 /**
580 * All of the currently running global content providers. Keys are a
581 * string containing the provider's implementation class and values are a
582 * ContentProviderRecord object containing the data about it.
583 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700584 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
585 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586
587 /**
588 * List of content providers who have clients waiting for them. The
589 * application is currently being launched and the provider will be
590 * removed from this list once it is published.
591 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700592 final ArrayList<ContentProviderRecord> mLaunchingProviders
593 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594
595 /**
596 * Global set of specific Uri permissions that have been granted.
597 */
598 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
599 = new SparseArray<HashMap<Uri, UriPermission>>();
600
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800601 CoreSettingsObserver mCoreSettingsObserver;
602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 /**
604 * Thread-local storage used to carry caller permissions over through
605 * indirect content-provider access.
606 * @see #ActivityManagerService.openContentUri()
607 */
608 private class Identity {
609 public int pid;
610 public int uid;
611
612 Identity(int _pid, int _uid) {
613 pid = _pid;
614 uid = _uid;
615 }
616 }
617 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
618
619 /**
620 * All information we have collected about the runtime performance of
621 * any user id that can impact battery performance.
622 */
623 final BatteryStatsService mBatteryStatsService;
624
625 /**
626 * information about component usage
627 */
628 final UsageStatsService mUsageStatsService;
629
630 /**
631 * Current configuration information. HistoryRecord objects are given
632 * a reference to this object to indicate which configuration they are
633 * currently running in, so this object must be kept immutable.
634 */
635 Configuration mConfiguration = new Configuration();
636
637 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800638 * Current sequencing integer of the configuration, for skipping old
639 * configurations.
640 */
641 int mConfigurationSeq = 0;
642
643 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700644 * Hardware-reported OpenGLES version.
645 */
646 final int GL_ES_VERSION;
647
648 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 * List of initialization arguments to pass to all processes when binding applications to them.
650 * For example, references to the commonly used services.
651 */
652 HashMap<String, IBinder> mAppBindArgs;
653
654 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700655 * Temporary to avoid allocations. Protected by main lock.
656 */
657 final StringBuilder mStringBuilder = new StringBuilder(256);
658
659 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800660 * Used to control how we initialize the service.
661 */
662 boolean mStartRunning = false;
663 ComponentName mTopComponent;
664 String mTopAction;
665 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700666 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800667 boolean mSystemReady = false;
668 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700669 boolean mWaitingUpdate = false;
670 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700671 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700672 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800673
674 Context mContext;
675
676 int mFactoryTest;
677
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700678 boolean mCheckedForSetup;
679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700681 * The time at which we will allow normal application switches again,
682 * after a call to {@link #stopAppSwitches()}.
683 */
684 long mAppSwitchesAllowedTime;
685
686 /**
687 * This is set to true after the first switch after mAppSwitchesAllowedTime
688 * is set; any switches after that will clear the time.
689 */
690 boolean mDidAppSwitch;
691
692 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700693 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700694 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700695 long mLastPowerCheckRealtime;
696
697 /**
698 * Last time (in uptime) at which we checked for power usage.
699 */
700 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700701
702 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703 * Set while we are wanting to sleep, to prevent any
704 * activities from being started/resumed.
705 */
706 boolean mSleeping = false;
707
708 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700709 * Set if we are shutting down the system, similar to sleeping.
710 */
711 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712
713 /**
714 * Task identifier that activities are currently being started
715 * in. Incremented each time a new task is created.
716 * todo: Replace this with a TokenSpace class that generates non-repeating
717 * integers that won't wrap.
718 */
719 int mCurTask = 1;
720
721 /**
722 * Current sequence id for oom_adj computation traversal.
723 */
724 int mAdjSeq = 0;
725
726 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700727 * Current sequence id for process LRU updating.
728 */
729 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800730
731 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700732 * Keep track of the number of service processes we last found, to
733 * determine on the next iteration which should be B services.
734 */
735 int mNumServiceProcs = 0;
736 int mNewNumServiceProcs = 0;
737
738 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 * System monitoring: number of processes that died since the last
740 * N procs were started.
741 */
742 int[] mProcDeaths = new int[20];
743
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700744 /**
745 * This is set if we had to do a delayed dexopt of an app before launching
746 * it, to increasing the ANR timeouts in that case.
747 */
748 boolean mDidDexOpt;
749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800750 String mDebugApp = null;
751 boolean mWaitForDebugger = false;
752 boolean mDebugTransient = false;
753 String mOrigDebugApp = null;
754 boolean mOrigWaitForDebugger = false;
755 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700756 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700757 String mProfileApp = null;
758 ProcessRecord mProfileProc = null;
759 String mProfileFile;
760 ParcelFileDescriptor mProfileFd;
761 int mProfileType = 0;
762 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800763
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700764 final RemoteCallbackList<IActivityWatcher> mWatchers
765 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700766
767 final RemoteCallbackList<IProcessObserver> mProcessObservers
768 = new RemoteCallbackList<IProcessObserver>();
769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 /**
771 * Callback of last caller to {@link #requestPss}.
772 */
773 Runnable mRequestPssCallback;
774
775 /**
776 * Remaining processes for which we are waiting results from the last
777 * call to {@link #requestPss}.
778 */
779 final ArrayList<ProcessRecord> mRequestPssList
780 = new ArrayList<ProcessRecord>();
781
782 /**
783 * Runtime statistics collection thread. This object's lock is used to
784 * protect all related state.
785 */
786 final Thread mProcessStatsThread;
787
788 /**
789 * Used to collect process stats when showing not responding dialog.
790 * Protected by mProcessStatsThread.
791 */
792 final ProcessStats mProcessStats = new ProcessStats(
793 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700794 final AtomicLong mLastCpuTime = new AtomicLong(0);
795 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 long mLastWriteTime = 0;
798
799 /**
800 * Set to true after the system has finished booting.
801 */
802 boolean mBooted = false;
803
Dianne Hackborn7d608422011-08-07 16:24:18 -0700804 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700805 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806
807 WindowManagerService mWindowManager;
808
809 static ActivityManagerService mSelf;
810 static ActivityThread mSystemThread;
811
812 private final class AppDeathRecipient implements IBinder.DeathRecipient {
813 final ProcessRecord mApp;
814 final int mPid;
815 final IApplicationThread mAppThread;
816
817 AppDeathRecipient(ProcessRecord app, int pid,
818 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800819 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820 TAG, "New death recipient " + this
821 + " for thread " + thread.asBinder());
822 mApp = app;
823 mPid = pid;
824 mAppThread = thread;
825 }
826
827 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800828 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 TAG, "Death received in " + this
830 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800831 synchronized(ActivityManagerService.this) {
832 appDiedLocked(mApp, mPid, mAppThread);
833 }
834 }
835 }
836
837 static final int SHOW_ERROR_MSG = 1;
838 static final int SHOW_NOT_RESPONDING_MSG = 2;
839 static final int SHOW_FACTORY_ERROR_MSG = 3;
840 static final int UPDATE_CONFIGURATION_MSG = 4;
841 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
842 static final int WAIT_FOR_DEBUGGER_MSG = 6;
843 static final int BROADCAST_INTENT_MSG = 7;
844 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800845 static final int SERVICE_TIMEOUT_MSG = 12;
846 static final int UPDATE_TIME_ZONE = 13;
847 static final int SHOW_UID_ERROR_MSG = 14;
848 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700850 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700851 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800852 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700853 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
854 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700855 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700856 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700857 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700858 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700859 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700860 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
861 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700862 static final int REPORT_MEM_USAGE = 33;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863
864 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700865 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700866 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867
868 final Handler mHandler = new Handler() {
869 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800870 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 //}
872
873 public void handleMessage(Message msg) {
874 switch (msg.what) {
875 case SHOW_ERROR_MSG: {
876 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 synchronized (ActivityManagerService.this) {
878 ProcessRecord proc = (ProcessRecord)data.get("app");
879 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800880 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 return;
882 }
883 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700884 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800885 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 d.show();
887 proc.crashDialog = d;
888 } else {
889 // The device is asleep, so just pretend that the user
890 // saw a crash dialog and hit "force quit".
891 res.set(0);
892 }
893 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700894
895 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 } break;
897 case SHOW_NOT_RESPONDING_MSG: {
898 synchronized (ActivityManagerService.this) {
899 HashMap data = (HashMap) msg.obj;
900 ProcessRecord proc = (ProcessRecord)data.get("app");
901 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800902 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 return;
904 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800905
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700906 Intent intent = new Intent("android.intent.action.ANR");
907 if (!mProcessesReady) {
908 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
909 }
910 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800911 null, null, 0, null, null, null,
912 false, false, MY_PID, Process.SYSTEM_UID);
913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700915 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 d.show();
917 proc.anrDialog = d;
918 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700919
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700920 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700922 case SHOW_STRICT_MODE_VIOLATION_MSG: {
923 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
924 synchronized (ActivityManagerService.this) {
925 ProcessRecord proc = (ProcessRecord) data.get("app");
926 if (proc == null) {
927 Slog.e(TAG, "App not found when showing strict mode dialog.");
928 break;
929 }
930 if (proc.crashDialog != null) {
931 Slog.e(TAG, "App already has strict mode dialog: " + proc);
932 return;
933 }
934 AppErrorResult res = (AppErrorResult) data.get("result");
935 if (!mSleeping && !mShuttingDown) {
936 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
937 d.show();
938 proc.crashDialog = d;
939 } else {
940 // The device is asleep, so just pretend that the user
941 // saw a crash dialog and hit "force quit".
942 res.set(0);
943 }
944 }
945 ensureBootCompleted();
946 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 case SHOW_FACTORY_ERROR_MSG: {
948 Dialog d = new FactoryErrorDialog(
949 mContext, msg.getData().getCharSequence("msg"));
950 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700951 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 } break;
953 case UPDATE_CONFIGURATION_MSG: {
954 final ContentResolver resolver = mContext.getContentResolver();
955 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
956 } break;
957 case GC_BACKGROUND_PROCESSES_MSG: {
958 synchronized (ActivityManagerService.this) {
959 performAppGcsIfAppropriateLocked();
960 }
961 } break;
962 case WAIT_FOR_DEBUGGER_MSG: {
963 synchronized (ActivityManagerService.this) {
964 ProcessRecord app = (ProcessRecord)msg.obj;
965 if (msg.arg1 != 0) {
966 if (!app.waitedForDebugger) {
967 Dialog d = new AppWaitingForDebuggerDialog(
968 ActivityManagerService.this,
969 mContext, app);
970 app.waitDialog = d;
971 app.waitedForDebugger = true;
972 d.show();
973 }
974 } else {
975 if (app.waitDialog != null) {
976 app.waitDialog.dismiss();
977 app.waitDialog = null;
978 }
979 }
980 }
981 } break;
982 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800983 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 TAG, "Received BROADCAST_INTENT_MSG");
985 processNextBroadcast(true);
986 } break;
987 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700988 synchronized (ActivityManagerService.this) {
989 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700993 if (mDidDexOpt) {
994 mDidDexOpt = false;
995 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
996 nmsg.obj = msg.obj;
997 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
998 return;
999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 serviceTimeout((ProcessRecord)msg.obj);
1001 } break;
1002 case UPDATE_TIME_ZONE: {
1003 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001004 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1005 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001006 if (r.thread != null) {
1007 try {
1008 r.thread.updateTimeZone();
1009 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001010 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 }
1012 }
1013 }
1014 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001015 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001016 case CLEAR_DNS_CACHE: {
1017 synchronized (ActivityManagerService.this) {
1018 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1019 ProcessRecord r = mLruProcesses.get(i);
1020 if (r.thread != null) {
1021 try {
1022 r.thread.clearDnsCache();
1023 } catch (RemoteException ex) {
1024 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1025 }
1026 }
1027 }
1028 }
1029 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001030 case UPDATE_HTTP_PROXY: {
1031 ProxyProperties proxy = (ProxyProperties)msg.obj;
1032 String host = "";
1033 String port = "";
1034 String exclList = "";
1035 if (proxy != null) {
1036 host = proxy.getHost();
1037 port = Integer.toString(proxy.getPort());
1038 exclList = proxy.getExclusionList();
1039 }
1040 synchronized (ActivityManagerService.this) {
1041 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1042 ProcessRecord r = mLruProcesses.get(i);
1043 if (r.thread != null) {
1044 try {
1045 r.thread.setHttpProxy(host, port, exclList);
1046 } catch (RemoteException ex) {
1047 Slog.w(TAG, "Failed to update http proxy for: " +
1048 r.info.processName);
1049 }
1050 }
1051 }
1052 }
1053 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 case SHOW_UID_ERROR_MSG: {
1055 // XXX This is a temporary dialog, no need to localize.
1056 AlertDialog d = new BaseErrorDialog(mContext);
1057 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1058 d.setCancelable(false);
1059 d.setTitle("System UIDs Inconsistent");
1060 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 +02001061 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1063 mUidAlert = d;
1064 d.show();
1065 } break;
1066 case IM_FEELING_LUCKY_MSG: {
1067 if (mUidAlert != null) {
1068 mUidAlert.dismiss();
1069 mUidAlert = null;
1070 }
1071 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001072 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001073 if (mDidDexOpt) {
1074 mDidDexOpt = false;
1075 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1076 nmsg.obj = msg.obj;
1077 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1078 return;
1079 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001080 ProcessRecord app = (ProcessRecord)msg.obj;
1081 synchronized (ActivityManagerService.this) {
1082 processStartTimedOutLocked(app);
1083 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001084 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001085 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1086 synchronized (ActivityManagerService.this) {
1087 doPendingActivityLaunchesLocked(true);
1088 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001089 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001090 case KILL_APPLICATION_MSG: {
1091 synchronized (ActivityManagerService.this) {
1092 int uid = msg.arg1;
1093 boolean restart = (msg.arg2 == 1);
1094 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001095 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001096 }
1097 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001098 case FINALIZE_PENDING_INTENT_MSG: {
1099 ((PendingIntentRecord)msg.obj).completeFinalize();
1100 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001101 case POST_HEAVY_NOTIFICATION_MSG: {
1102 INotificationManager inm = NotificationManager.getService();
1103 if (inm == null) {
1104 return;
1105 }
1106
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001107 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001108 ProcessRecord process = root.app;
1109 if (process == null) {
1110 return;
1111 }
1112
1113 try {
1114 Context context = mContext.createPackageContext(process.info.packageName, 0);
1115 String text = mContext.getString(R.string.heavy_weight_notification,
1116 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1117 Notification notification = new Notification();
1118 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1119 notification.when = 0;
1120 notification.flags = Notification.FLAG_ONGOING_EVENT;
1121 notification.tickerText = text;
1122 notification.defaults = 0; // please be quiet
1123 notification.sound = null;
1124 notification.vibrate = null;
1125 notification.setLatestEventInfo(context, text,
1126 mContext.getText(R.string.heavy_weight_notification_detail),
1127 PendingIntent.getActivity(mContext, 0, root.intent,
1128 PendingIntent.FLAG_CANCEL_CURRENT));
1129
1130 try {
1131 int[] outId = new int[1];
1132 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1133 notification, outId);
1134 } catch (RuntimeException e) {
1135 Slog.w(ActivityManagerService.TAG,
1136 "Error showing notification for heavy-weight app", e);
1137 } catch (RemoteException e) {
1138 }
1139 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001140 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001141 }
1142 } break;
1143 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1144 INotificationManager inm = NotificationManager.getService();
1145 if (inm == null) {
1146 return;
1147 }
1148 try {
1149 inm.cancelNotification("android",
1150 R.string.heavy_weight_notification);
1151 } catch (RuntimeException e) {
1152 Slog.w(ActivityManagerService.TAG,
1153 "Error canceling notification for service", e);
1154 } catch (RemoteException e) {
1155 }
1156 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001157 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1158 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001159 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001160 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001161 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1162 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001163 }
1164 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001165 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1166 synchronized (ActivityManagerService.this) {
1167 ActivityRecord ar = (ActivityRecord)msg.obj;
1168 if (mCompatModeDialog != null) {
1169 if (mCompatModeDialog.mAppInfo.packageName.equals(
1170 ar.info.applicationInfo.packageName)) {
1171 return;
1172 }
1173 mCompatModeDialog.dismiss();
1174 mCompatModeDialog = null;
1175 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001176 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001177 if (mCompatModePackages.getPackageAskCompatModeLocked(
1178 ar.packageName)) {
1179 int mode = mCompatModePackages.computeCompatModeLocked(
1180 ar.info.applicationInfo);
1181 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1182 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1183 mCompatModeDialog = new CompatModeDialog(
1184 ActivityManagerService.this, mContext,
1185 ar.info.applicationInfo);
1186 mCompatModeDialog.show();
1187 }
1188 }
1189 }
1190 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001191 break;
1192 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001193 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001194 final int pid = msg.arg1;
1195 final int uid = msg.arg2;
1196 final boolean foregroundActivities = (Boolean) msg.obj;
1197 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001198 break;
1199 }
1200 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001201 final int pid = msg.arg1;
1202 final int uid = msg.arg2;
1203 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001204 break;
1205 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001206 case REPORT_MEM_USAGE: {
1207 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1208 if (!isDebuggable) {
1209 return;
1210 }
1211 synchronized (ActivityManagerService.this) {
1212 long now = SystemClock.uptimeMillis();
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001213 if (now < (mLastMemUsageReportTime+5*60*1000)) {
1214 // Don't report more than every 5 minutes to somewhat
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001215 // avoid spamming.
1216 return;
1217 }
1218 mLastMemUsageReportTime = now;
1219 }
1220 Thread thread = new Thread() {
1221 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001222 StringBuilder dropBuilder = new StringBuilder(1024);
1223 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08001224 StringWriter oomSw = new StringWriter();
1225 PrintWriter oomPw = new PrintWriter(oomSw);
1226 StringWriter catSw = new StringWriter();
1227 PrintWriter catPw = new PrintWriter(catSw);
1228 String[] emptyArgs = new String[] { };
1229 StringBuilder tag = new StringBuilder(128);
1230 StringBuilder stack = new StringBuilder(128);
1231 tag.append("Low on memory -- ");
1232 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw,
1233 tag, stack);
1234 dropBuilder.append(stack);
1235 dropBuilder.append('\n');
1236 dropBuilder.append('\n');
1237 String oomString = oomSw.toString();
1238 dropBuilder.append(oomString);
1239 dropBuilder.append('\n');
1240 logBuilder.append(oomString);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001241 try {
1242 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1243 "procrank", });
1244 final InputStreamReader converter = new InputStreamReader(
1245 proc.getInputStream());
1246 BufferedReader in = new BufferedReader(converter);
1247 String line;
1248 while (true) {
1249 line = in.readLine();
1250 if (line == null) {
1251 break;
1252 }
1253 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001254 logBuilder.append(line);
1255 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001256 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001257 dropBuilder.append(line);
1258 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001259 }
1260 converter.close();
1261 } catch (IOException e) {
1262 }
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001263 synchronized (ActivityManagerService.this) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08001264 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001265 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001266 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001267 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001268 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001269 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001270 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001271 dropBuilder.append(catSw.toString());
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001272 addErrorToDropBox("lowmem", null, "system_server", null,
1273 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001274 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001275 synchronized (ActivityManagerService.this) {
1276 long now = SystemClock.uptimeMillis();
1277 if (mLastMemUsageReportTime < now) {
1278 mLastMemUsageReportTime = now;
1279 }
1280 }
1281 }
1282 };
1283 thread.start();
1284 break;
1285 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 }
1287 }
1288 };
1289
1290 public static void setSystemProcess() {
1291 try {
1292 ActivityManagerService m = mSelf;
1293
1294 ServiceManager.addService("activity", m);
1295 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001296 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 if (MONITOR_CPU_USAGE) {
1298 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1299 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 ServiceManager.addService("permission", new PermissionController(m));
1301
1302 ApplicationInfo info =
1303 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001304 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001305 mSystemThread.installSystemApplicationInfo(info);
1306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 synchronized (mSelf) {
1308 ProcessRecord app = mSelf.newProcessRecordLocked(
1309 mSystemThread.getApplicationThread(), info,
1310 info.processName);
1311 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001312 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001313 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1315 synchronized (mSelf.mPidsSelfLocked) {
1316 mSelf.mPidsSelfLocked.put(app.pid, app);
1317 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001318 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 }
1320 } catch (PackageManager.NameNotFoundException e) {
1321 throw new RuntimeException(
1322 "Unable to find android system package", e);
1323 }
1324 }
1325
1326 public void setWindowManager(WindowManagerService wm) {
1327 mWindowManager = wm;
1328 }
1329
1330 public static final Context main(int factoryTest) {
1331 AThread thr = new AThread();
1332 thr.start();
1333
1334 synchronized (thr) {
1335 while (thr.mService == null) {
1336 try {
1337 thr.wait();
1338 } catch (InterruptedException e) {
1339 }
1340 }
1341 }
1342
1343 ActivityManagerService m = thr.mService;
1344 mSelf = m;
1345 ActivityThread at = ActivityThread.systemMain();
1346 mSystemThread = at;
1347 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001348 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 m.mContext = context;
1350 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001351 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352
1353 m.mBatteryStatsService.publish(context);
1354 m.mUsageStatsService.publish(context);
1355
1356 synchronized (thr) {
1357 thr.mReady = true;
1358 thr.notifyAll();
1359 }
1360
1361 m.startRunning(null, null, null, null);
1362
1363 return context;
1364 }
1365
1366 public static ActivityManagerService self() {
1367 return mSelf;
1368 }
1369
1370 static class AThread extends Thread {
1371 ActivityManagerService mService;
1372 boolean mReady = false;
1373
1374 public AThread() {
1375 super("ActivityManager");
1376 }
1377
1378 public void run() {
1379 Looper.prepare();
1380
1381 android.os.Process.setThreadPriority(
1382 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001383 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384
1385 ActivityManagerService m = new ActivityManagerService();
1386
1387 synchronized (this) {
1388 mService = m;
1389 notifyAll();
1390 }
1391
1392 synchronized (this) {
1393 while (!mReady) {
1394 try {
1395 wait();
1396 } catch (InterruptedException e) {
1397 }
1398 }
1399 }
1400
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001401 // For debug builds, log event loop stalls to dropbox for analysis.
1402 if (StrictMode.conditionallyEnableDebugLogging()) {
1403 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1404 }
1405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 Looper.loop();
1407 }
1408 }
1409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 static class MemBinder extends Binder {
1411 ActivityManagerService mActivityManagerService;
1412 MemBinder(ActivityManagerService activityManagerService) {
1413 mActivityManagerService = activityManagerService;
1414 }
1415
1416 @Override
1417 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001418 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1419 != PackageManager.PERMISSION_GRANTED) {
1420 pw.println("Permission Denial: can't dump meminfo from from pid="
1421 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1422 + " without permission " + android.Manifest.permission.DUMP);
1423 return;
1424 }
1425
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001426 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
Dianne Hackborn672342c2011-11-29 11:29:02 -08001427 false, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 }
1429 }
1430
Chet Haase9c1e23b2011-03-24 10:51:31 -07001431 static class GraphicsBinder extends Binder {
1432 ActivityManagerService mActivityManagerService;
1433 GraphicsBinder(ActivityManagerService activityManagerService) {
1434 mActivityManagerService = activityManagerService;
1435 }
1436
1437 @Override
1438 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001439 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1440 != PackageManager.PERMISSION_GRANTED) {
1441 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1442 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1443 + " without permission " + android.Manifest.permission.DUMP);
1444 return;
1445 }
1446
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001447 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001448 }
1449 }
1450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 static class CpuBinder extends Binder {
1452 ActivityManagerService mActivityManagerService;
1453 CpuBinder(ActivityManagerService activityManagerService) {
1454 mActivityManagerService = activityManagerService;
1455 }
1456
1457 @Override
1458 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001459 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1460 != PackageManager.PERMISSION_GRANTED) {
1461 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1462 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1463 + " without permission " + android.Manifest.permission.DUMP);
1464 return;
1465 }
1466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001468 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1469 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1470 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 }
1472 }
1473 }
1474
1475 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001476 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 File dataDir = Environment.getDataDirectory();
1479 File systemDir = new File(dataDir, "system");
1480 systemDir.mkdirs();
1481 mBatteryStatsService = new BatteryStatsService(new File(
1482 systemDir, "batterystats.bin").toString());
1483 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001484 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001485 mOnBattery = DEBUG_POWER ? true
1486 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001487 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001489 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001490 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491
Jack Palevichb90d28c2009-07-22 15:35:24 -07001492 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1493 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1494
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001495 mConfiguration.setToDefaults();
1496 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08001497 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001498 mProcessStats.init();
1499
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001500 mCompatModePackages = new CompatModePackages(this, systemDir);
1501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 // Add ourself to the Watchdog monitors.
1503 Watchdog.getInstance().addMonitor(this);
1504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 mProcessStatsThread = new Thread("ProcessStats") {
1506 public void run() {
1507 while (true) {
1508 try {
1509 try {
1510 synchronized(this) {
1511 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001512 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001514 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 // + ", write delay=" + nextWriteDelay);
1516 if (nextWriteDelay < nextCpuDelay) {
1517 nextCpuDelay = nextWriteDelay;
1518 }
1519 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001520 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 this.wait(nextCpuDelay);
1522 }
1523 }
1524 } catch (InterruptedException e) {
1525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 updateCpuStatsNow();
1527 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001528 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001529 }
1530 }
1531 }
1532 };
1533 mProcessStatsThread.start();
1534 }
1535
1536 @Override
1537 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1538 throws RemoteException {
1539 try {
1540 return super.onTransact(code, data, reply, flags);
1541 } catch (RuntimeException e) {
1542 // The activity manager only throws security exceptions, so let's
1543 // log all others.
1544 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001545 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 }
1547 throw e;
1548 }
1549 }
1550
1551 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001552 final long now = SystemClock.uptimeMillis();
1553 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1554 return;
1555 }
1556 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1557 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 mProcessStatsThread.notify();
1559 }
1560 }
1561 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 void updateCpuStatsNow() {
1564 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001565 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 final long now = SystemClock.uptimeMillis();
1567 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001570 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1571 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 haveNewCpuStats = true;
1573 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001574 //Slog.i(TAG, mProcessStats.printCurrentState());
1575 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001576 // + mProcessStats.getTotalCpuPercent() + "%");
1577
Joe Onorato8a9b2202010-02-26 18:56:32 -08001578 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 if ("true".equals(SystemProperties.get("events.cpu"))) {
1580 int user = mProcessStats.getLastUserTime();
1581 int system = mProcessStats.getLastSystemTime();
1582 int iowait = mProcessStats.getLastIoWaitTime();
1583 int irq = mProcessStats.getLastIrqTime();
1584 int softIrq = mProcessStats.getLastSoftIrqTime();
1585 int idle = mProcessStats.getLastIdleTime();
1586
1587 int total = user + system + iowait + irq + softIrq + idle;
1588 if (total == 0) total = 1;
1589
Doug Zongker2bec3d42009-12-04 12:52:44 -08001590 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001591 ((user+system+iowait+irq+softIrq) * 100) / total,
1592 (user * 100) / total,
1593 (system * 100) / total,
1594 (iowait * 100) / total,
1595 (irq * 100) / total,
1596 (softIrq * 100) / total);
1597 }
1598 }
1599
Amith Yamasanie43530a2009-08-21 13:11:37 -07001600 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001601 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001602 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 synchronized(mPidsSelfLocked) {
1604 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001605 if (mOnBattery) {
1606 int perc = bstats.startAddingCpuLocked();
1607 int totalUTime = 0;
1608 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001609 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001611 ProcessStats.Stats st = mProcessStats.getStats(i);
1612 if (!st.working) {
1613 continue;
1614 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001615 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001616 int otherUTime = (st.rel_utime*perc)/100;
1617 int otherSTime = (st.rel_stime*perc)/100;
1618 totalUTime += otherUTime;
1619 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620 if (pr != null) {
1621 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001622 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1623 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001624 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001625 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001626 } else {
1627 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001628 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001629 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001630 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1631 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001632 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001633 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001634 }
1635 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001636 bstats.finishAddingCpuLocked(perc, totalUTime,
1637 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001638 }
1639 }
1640 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1643 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001644 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 }
1646 }
1647 }
1648 }
1649
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001650 @Override
1651 public void batteryNeedsCpuUpdate() {
1652 updateCpuStatsNow();
1653 }
1654
1655 @Override
1656 public void batteryPowerChanged(boolean onBattery) {
1657 // When plugging in, update the CPU stats first before changing
1658 // the plug state.
1659 updateCpuStatsNow();
1660 synchronized (this) {
1661 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001662 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001663 }
1664 }
1665 }
1666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001667 /**
1668 * Initialize the application bind args. These are passed to each
1669 * process when the bindApplication() IPC is sent to the process. They're
1670 * lazily setup to make sure the services are running when they're asked for.
1671 */
1672 private HashMap<String, IBinder> getCommonServicesLocked() {
1673 if (mAppBindArgs == null) {
1674 mAppBindArgs = new HashMap<String, IBinder>();
1675
1676 // Setup the application init args
1677 mAppBindArgs.put("package", ServiceManager.getService("package"));
1678 mAppBindArgs.put("window", ServiceManager.getService("window"));
1679 mAppBindArgs.put(Context.ALARM_SERVICE,
1680 ServiceManager.getService(Context.ALARM_SERVICE));
1681 }
1682 return mAppBindArgs;
1683 }
1684
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001685 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 if (mFocusedActivity != r) {
1687 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001688 if (r != null) {
1689 mWindowManager.setFocusedApp(r.appToken, true);
1690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001691 }
1692 }
1693
Dianne Hackborn906497c2010-05-10 15:57:38 -07001694 private final void updateLruProcessInternalLocked(ProcessRecord app,
1695 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001696 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001697 int lrui = mLruProcesses.indexOf(app);
1698 if (lrui >= 0) mLruProcesses.remove(lrui);
1699
1700 int i = mLruProcesses.size()-1;
1701 int skipTop = 0;
1702
Dianne Hackborn906497c2010-05-10 15:57:38 -07001703 app.lruSeq = mLruSeq;
1704
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001705 // compute the new weight for this process.
1706 if (updateActivityTime) {
1707 app.lastActivityTime = SystemClock.uptimeMillis();
1708 }
1709 if (app.activities.size() > 0) {
1710 // If this process has activities, we more strongly want to keep
1711 // it around.
1712 app.lruWeight = app.lastActivityTime;
1713 } else if (app.pubProviders.size() > 0) {
1714 // If this process contains content providers, we want to keep
1715 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001716 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001717 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001718 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001719 } else {
1720 // If this process doesn't have activities, we less strongly
1721 // want to keep it around, and generally want to avoid getting
1722 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001723 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001724 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001725 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001726 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001727
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001728 while (i >= 0) {
1729 ProcessRecord p = mLruProcesses.get(i);
1730 // If this app shouldn't be in front of the first N background
1731 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001732 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001733 skipTop--;
1734 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001735 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001736 mLruProcesses.add(i+1, app);
1737 break;
1738 }
1739 i--;
1740 }
1741 if (i < 0) {
1742 mLruProcesses.add(0, app);
1743 }
1744
Dianne Hackborn906497c2010-05-10 15:57:38 -07001745 // If the app is currently using a content provider or service,
1746 // bump those processes as well.
1747 if (app.connections.size() > 0) {
1748 for (ConnectionRecord cr : app.connections) {
1749 if (cr.binding != null && cr.binding.service != null
1750 && cr.binding.service.app != null
1751 && cr.binding.service.app.lruSeq != mLruSeq) {
1752 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1753 updateActivityTime, i+1);
1754 }
1755 }
1756 }
1757 if (app.conProviders.size() > 0) {
1758 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001759 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1760 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001761 updateActivityTime, i+1);
1762 }
1763 }
1764 }
1765
Joe Onorato8a9b2202010-02-26 18:56:32 -08001766 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001767 if (oomAdj) {
1768 updateOomAdjLocked();
1769 }
1770 }
1771
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001772 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001773 boolean oomAdj, boolean updateActivityTime) {
1774 mLruSeq++;
1775 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1776 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001777
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001778 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001779 String processName, int uid) {
1780 if (uid == Process.SYSTEM_UID) {
1781 // The system gets to run in any process. If there are multiple
1782 // processes with the same uid, just pick the first (this
1783 // should never happen).
1784 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1785 processName);
1786 return procs != null ? procs.valueAt(0) : null;
1787 }
1788 ProcessRecord proc = mProcessNames.get(processName, uid);
1789 return proc;
1790 }
1791
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001792 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001793 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001794 try {
1795 if (pm.performDexOpt(packageName)) {
1796 mDidDexOpt = true;
1797 }
1798 } catch (RemoteException e) {
1799 }
1800 }
1801
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001802 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001803 int transit = mWindowManager.getPendingAppTransition();
1804 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1805 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1806 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1807 }
1808
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001809 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001810 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001811 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001812 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1813 // We don't have to do anything more if:
1814 // (1) There is an existing application record; and
1815 // (2) The caller doesn't think it is dead, OR there is no thread
1816 // object attached to it so we know it couldn't have crashed; and
1817 // (3) There is a pid assigned to it, so it is either starting or
1818 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001819 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001820 + " app=" + app + " knownToBeDead=" + knownToBeDead
1821 + " thread=" + (app != null ? app.thread : null)
1822 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001823 if (app != null && app.pid > 0) {
1824 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001825 // We already have the app running, or are waiting for it to
1826 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001827 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001828 // If this is a new package in the process, add the package to the list
1829 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001830 return app;
1831 } else {
1832 // An application record is attached to a previous process,
1833 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001834 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001835 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001837 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 String hostingNameStr = hostingName != null
1840 ? hostingName.flattenToShortString() : null;
1841
1842 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1843 // If we are in the background, then check to see if this process
1844 // is bad. If so, we will just silently fail.
1845 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001846 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1847 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001848 return null;
1849 }
1850 } else {
1851 // When the user is explicitly starting a process, then clear its
1852 // crash count so that we won't make it bad until they see at
1853 // least one crash dialog again, and make the process good again
1854 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001855 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1856 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001857 mProcessCrashTimes.remove(info.processName, info.uid);
1858 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001859 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001860 info.processName);
1861 mBadProcesses.remove(info.processName, info.uid);
1862 if (app != null) {
1863 app.bad = false;
1864 }
1865 }
1866 }
1867
1868 if (app == null) {
1869 app = newProcessRecordLocked(null, info, processName);
1870 mProcessNames.put(processName, info.uid, app);
1871 } else {
1872 // If this is a new package in the process, add the package to the list
1873 app.addPackage(info.packageName);
1874 }
1875
1876 // If the system is not ready yet, then hold off on starting this
1877 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001878 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001879 && !isAllowedWhileBooting(info)
1880 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001881 if (!mProcessesOnHold.contains(app)) {
1882 mProcessesOnHold.add(app);
1883 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001884 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001885 return app;
1886 }
1887
1888 startProcessLocked(app, hostingType, hostingNameStr);
1889 return (app.pid != 0) ? app : null;
1890 }
1891
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001892 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1893 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1894 }
1895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001896 private final void startProcessLocked(ProcessRecord app,
1897 String hostingType, String hostingNameStr) {
1898 if (app.pid > 0 && app.pid != MY_PID) {
1899 synchronized (mPidsSelfLocked) {
1900 mPidsSelfLocked.remove(app.pid);
1901 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1902 }
1903 app.pid = 0;
1904 }
1905
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001906 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1907 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001908 mProcessesOnHold.remove(app);
1909
1910 updateCpuStats();
1911
1912 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1913 mProcDeaths[0] = 0;
1914
1915 try {
1916 int uid = app.info.uid;
1917 int[] gids = null;
1918 try {
1919 gids = mContext.getPackageManager().getPackageGids(
1920 app.info.packageName);
1921 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001922 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001923 }
1924 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1925 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1926 && mTopComponent != null
1927 && app.processName.equals(mTopComponent.getPackageName())) {
1928 uid = 0;
1929 }
1930 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1931 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1932 uid = 0;
1933 }
1934 }
1935 int debugFlags = 0;
1936 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1937 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001938 // Also turn on CheckJNI for debuggable apps. It's quite
1939 // awkward to turn on otherwise.
1940 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001941 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001942 // Run the app in safe mode if its manifest requests so or the
1943 // system is booted in safe mode.
1944 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1945 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001946 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1947 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001948 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1949 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1950 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001951 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1952 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1953 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001954 if ("1".equals(SystemProperties.get("debug.assert"))) {
1955 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1956 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001957
1958 // Start the process. It will either succeed and return a result containing
1959 // the PID of the new process, or else throw a RuntimeException.
1960 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001961 app.processName, uid, uid, gids, debugFlags,
1962 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1965 synchronized (bs) {
1966 if (bs.isOnBattery()) {
1967 app.batteryStats.incStartsLocked();
1968 }
1969 }
1970
Jeff Brown3f9dd282011-07-08 20:02:19 -07001971 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001972 app.processName, hostingType,
1973 hostingNameStr != null ? hostingNameStr : "");
1974
1975 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001976 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001977 }
1978
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001979 StringBuilder buf = mStringBuilder;
1980 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001981 buf.append("Start proc ");
1982 buf.append(app.processName);
1983 buf.append(" for ");
1984 buf.append(hostingType);
1985 if (hostingNameStr != null) {
1986 buf.append(" ");
1987 buf.append(hostingNameStr);
1988 }
1989 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001990 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001991 buf.append(" uid=");
1992 buf.append(uid);
1993 buf.append(" gids={");
1994 if (gids != null) {
1995 for (int gi=0; gi<gids.length; gi++) {
1996 if (gi != 0) buf.append(", ");
1997 buf.append(gids[gi]);
1998
1999 }
2000 }
2001 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002002 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07002003 app.pid = startResult.pid;
2004 app.usingWrapper = startResult.usingWrapper;
2005 app.removed = false;
2006 synchronized (mPidsSelfLocked) {
2007 this.mPidsSelfLocked.put(startResult.pid, app);
2008 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2009 msg.obj = app;
2010 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2011 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002012 }
2013 } catch (RuntimeException e) {
2014 // XXX do better error recovery.
2015 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002016 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002017 }
2018 }
2019
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002020 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002021 if (resumed) {
2022 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2023 } else {
2024 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2025 }
2026 }
2027
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002028 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002029 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2030 && mTopAction == null) {
2031 // We are running in factory test mode, but unable to find
2032 // the factory test app, so just sit around displaying the
2033 // error message and don't try to start anything.
2034 return false;
2035 }
2036 Intent intent = new Intent(
2037 mTopAction,
2038 mTopData != null ? Uri.parse(mTopData) : null);
2039 intent.setComponent(mTopComponent);
2040 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2041 intent.addCategory(Intent.CATEGORY_HOME);
2042 }
2043 ActivityInfo aInfo =
2044 intent.resolveActivityInfo(mContext.getPackageManager(),
2045 STOCK_PM_FLAGS);
2046 if (aInfo != null) {
2047 intent.setComponent(new ComponentName(
2048 aInfo.applicationInfo.packageName, aInfo.name));
2049 // Don't do this if the home app is currently being
2050 // instrumented.
2051 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2052 aInfo.applicationInfo.uid);
2053 if (app == null || app.instrumentationClass == null) {
2054 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002055 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002056 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002057 }
2058 }
2059
2060
2061 return true;
2062 }
2063
2064 /**
2065 * Starts the "new version setup screen" if appropriate.
2066 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002067 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002068 // Only do this once per boot.
2069 if (mCheckedForSetup) {
2070 return;
2071 }
2072
2073 // We will show this screen if the current one is a different
2074 // version than the last one shown, and we are not running in
2075 // low-level factory test mode.
2076 final ContentResolver resolver = mContext.getContentResolver();
2077 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2078 Settings.Secure.getInt(resolver,
2079 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2080 mCheckedForSetup = true;
2081
2082 // See if we should be showing the platform update setup UI.
2083 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2084 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2085 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2086
2087 // We don't allow third party apps to replace this.
2088 ResolveInfo ri = null;
2089 for (int i=0; ris != null && i<ris.size(); i++) {
2090 if ((ris.get(i).activityInfo.applicationInfo.flags
2091 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2092 ri = ris.get(i);
2093 break;
2094 }
2095 }
2096
2097 if (ri != null) {
2098 String vers = ri.activityInfo.metaData != null
2099 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2100 : null;
2101 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2102 vers = ri.activityInfo.applicationInfo.metaData.getString(
2103 Intent.METADATA_SETUP_VERSION);
2104 }
2105 String lastVers = Settings.Secure.getString(
2106 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2107 if (vers != null && !vers.equals(lastVers)) {
2108 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2109 intent.setComponent(new ComponentName(
2110 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002111 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002112 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002113 }
2114 }
2115 }
2116 }
2117
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002118 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002119 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002120 }
2121
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002122 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002123 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002124 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2125 }
2126 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002127
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002128 public void setFrontActivityScreenCompatMode(int mode) {
2129 synchronized (this) {
2130 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2131 }
2132 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002133
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002134 public int getPackageScreenCompatMode(String packageName) {
2135 synchronized (this) {
2136 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2137 }
2138 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002139
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002140 public void setPackageScreenCompatMode(String packageName, int mode) {
2141 synchronized (this) {
2142 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002143 }
2144 }
2145
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002146 public boolean getPackageAskScreenCompat(String packageName) {
2147 synchronized (this) {
2148 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2149 }
2150 }
2151
2152 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2153 synchronized (this) {
2154 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2155 }
2156 }
2157
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002158 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002159 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002160
2161 final int identHash = System.identityHashCode(r);
2162 updateUsageStats(r, true);
2163
2164 int i = mWatchers.beginBroadcast();
2165 while (i > 0) {
2166 i--;
2167 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2168 if (w != null) {
2169 try {
2170 w.activityResuming(identHash);
2171 } catch (RemoteException e) {
2172 }
2173 }
2174 }
2175 mWatchers.finishBroadcast();
2176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002177
Jeff Sharkeya4620792011-05-20 15:29:23 -07002178 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2179 int i = mProcessObservers.beginBroadcast();
2180 while (i > 0) {
2181 i--;
2182 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2183 if (observer != null) {
2184 try {
2185 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2186 } catch (RemoteException e) {
2187 }
2188 }
2189 }
2190 mProcessObservers.finishBroadcast();
2191 }
2192
2193 private void dispatchProcessDied(int pid, int uid) {
2194 int i = mProcessObservers.beginBroadcast();
2195 while (i > 0) {
2196 i--;
2197 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2198 if (observer != null) {
2199 try {
2200 observer.onProcessDied(pid, uid);
2201 } catch (RemoteException e) {
2202 }
2203 }
2204 }
2205 mProcessObservers.finishBroadcast();
2206 }
2207
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002208 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002209 final int N = mPendingActivityLaunches.size();
2210 if (N <= 0) {
2211 return;
2212 }
2213 for (int i=0; i<N; i++) {
2214 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002215 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002216 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2217 doResume && i == (N-1));
2218 }
2219 mPendingActivityLaunches.clear();
2220 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002221
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002222 public final int startActivity(IApplicationThread caller,
2223 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2224 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002225 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2226 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002227 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002228 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002229 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2230 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002231 }
2232
2233 public final WaitResult startActivityAndWait(IApplicationThread caller,
2234 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2235 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002236 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2237 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002238 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002239 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002240 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002241 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2242 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002243 return res;
2244 }
2245
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002246 public final int startActivityWithConfig(IApplicationThread caller,
2247 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2248 int grantedMode, IBinder resultTo,
2249 String resultWho, int requestCode, boolean onlyIfNeeded,
2250 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002251 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002252 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002253 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002254 }
2255
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002256 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002257 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002258 IBinder resultTo, String resultWho, int requestCode,
2259 int flagsMask, int flagsValues) {
2260 // Refuse possible leaked file descriptors
2261 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2262 throw new IllegalArgumentException("File descriptors passed in Intent");
2263 }
2264
2265 IIntentSender sender = intent.getTarget();
2266 if (!(sender instanceof PendingIntentRecord)) {
2267 throw new IllegalArgumentException("Bad PendingIntent object");
2268 }
2269
2270 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002271
2272 synchronized (this) {
2273 // If this is coming from the currently resumed activity, it is
2274 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002275 if (mMainStack.mResumedActivity != null
2276 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002277 Binder.getCallingUid()) {
2278 mAppSwitchesAllowedTime = 0;
2279 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002280 }
2281
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002282 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002283 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2284 }
2285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 public boolean startNextMatchingActivity(IBinder callingActivity,
2287 Intent intent) {
2288 // Refuse possible leaked file descriptors
2289 if (intent != null && intent.hasFileDescriptors() == true) {
2290 throw new IllegalArgumentException("File descriptors passed in Intent");
2291 }
2292
2293 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002294 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2295 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296 return false;
2297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298 if (r.app == null || r.app.thread == null) {
2299 // The caller is not running... d'oh!
2300 return false;
2301 }
2302 intent = new Intent(intent);
2303 // The caller is not allowed to change the data.
2304 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2305 // And we are resetting to find the next component...
2306 intent.setComponent(null);
2307
2308 ActivityInfo aInfo = null;
2309 try {
2310 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002311 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002313 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002314
2315 // Look for the original activity in the list...
2316 final int N = resolves != null ? resolves.size() : 0;
2317 for (int i=0; i<N; i++) {
2318 ResolveInfo rInfo = resolves.get(i);
2319 if (rInfo.activityInfo.packageName.equals(r.packageName)
2320 && rInfo.activityInfo.name.equals(r.info.name)) {
2321 // We found the current one... the next matching is
2322 // after it.
2323 i++;
2324 if (i<N) {
2325 aInfo = resolves.get(i).activityInfo;
2326 }
2327 break;
2328 }
2329 }
2330 } catch (RemoteException e) {
2331 }
2332
2333 if (aInfo == null) {
2334 // Nobody who is next!
2335 return false;
2336 }
2337
2338 intent.setComponent(new ComponentName(
2339 aInfo.applicationInfo.packageName, aInfo.name));
2340 intent.setFlags(intent.getFlags()&~(
2341 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2342 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2343 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2344 Intent.FLAG_ACTIVITY_NEW_TASK));
2345
2346 // Okay now we need to start the new activity, replacing the
2347 // currently running activity. This is a little tricky because
2348 // we want to start the new one as if the current one is finished,
2349 // but not finish the current one first so that there is no flicker.
2350 // And thus...
2351 final boolean wasFinishing = r.finishing;
2352 r.finishing = true;
2353
2354 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002355 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002356 final String resultWho = r.resultWho;
2357 final int requestCode = r.requestCode;
2358 r.resultTo = null;
2359 if (resultTo != null) {
2360 resultTo.removeResultsLocked(r, resultWho, requestCode);
2361 }
2362
2363 final long origId = Binder.clearCallingIdentity();
2364 // XXX we are not dealing with propagating grantedUriPermissions...
2365 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002366 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002367 r.resolvedType, null, 0, aInfo,
2368 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002369 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 Binder.restoreCallingIdentity(origId);
2371
2372 r.finishing = wasFinishing;
2373 if (res != START_SUCCESS) {
2374 return false;
2375 }
2376 return true;
2377 }
2378 }
2379
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002380 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 Intent intent, String resolvedType, IBinder resultTo,
2382 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002383
2384 // This is so super not safe, that only the system (or okay root)
2385 // can do it.
2386 final int callingUid = Binder.getCallingUid();
2387 if (callingUid != 0 && callingUid != Process.myUid()) {
2388 throw new SecurityException(
2389 "startActivityInPackage only available to the system");
2390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002391
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002392 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002393 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2394 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002395 }
2396
2397 public final int startActivities(IApplicationThread caller,
2398 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2399 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2400 }
2401
2402 public final int startActivitiesInPackage(int uid,
2403 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2404
2405 // This is so super not safe, that only the system (or okay root)
2406 // can do it.
2407 final int callingUid = Binder.getCallingUid();
2408 if (callingUid != 0 && callingUid != Process.myUid()) {
2409 throw new SecurityException(
2410 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002411 }
2412
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002413 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 }
2415
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002416 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002417 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002418 // Quick case: check if the top-most recent task is the same.
2419 if (N > 0 && mRecentTasks.get(0) == task) {
2420 return;
2421 }
2422 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002423 for (int i=0; i<N; i++) {
2424 TaskRecord tr = mRecentTasks.get(i);
2425 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2426 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2427 mRecentTasks.remove(i);
2428 i--;
2429 N--;
2430 if (task.intent == null) {
2431 // If the new recent task we are adding is not fully
2432 // specified, then replace it with the existing recent task.
2433 task = tr;
2434 }
2435 }
2436 }
2437 if (N >= MAX_RECENT_TASKS) {
2438 mRecentTasks.remove(N-1);
2439 }
2440 mRecentTasks.add(0, task);
2441 }
2442
2443 public void setRequestedOrientation(IBinder token,
2444 int requestedOrientation) {
2445 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002446 ActivityRecord r = mMainStack.isInStackLocked(token);
2447 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002448 return;
2449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002451 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002453 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002454 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 if (config != null) {
2456 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08002457 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002458 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002459 }
2460 }
2461 Binder.restoreCallingIdentity(origId);
2462 }
2463 }
2464
2465 public int getRequestedOrientation(IBinder token) {
2466 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002467 ActivityRecord r = mMainStack.isInStackLocked(token);
2468 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002469 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2470 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002471 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472 }
2473 }
2474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002475 /**
2476 * This is the internal entry point for handling Activity.finish().
2477 *
2478 * @param token The Binder token referencing the Activity we want to finish.
2479 * @param resultCode Result code, if any, from this Activity.
2480 * @param resultData Result data (Intent), if any, from this Activity.
2481 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002482 * @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 -08002483 */
2484 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2485 // Refuse possible leaked file descriptors
2486 if (resultData != null && resultData.hasFileDescriptors() == true) {
2487 throw new IllegalArgumentException("File descriptors passed in Intent");
2488 }
2489
2490 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002491 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002492 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002493 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 if (next != null) {
2495 // ask watcher if this is allowed
2496 boolean resumeOK = true;
2497 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002498 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002499 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002500 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002501 }
2502
2503 if (!resumeOK) {
2504 return false;
2505 }
2506 }
2507 }
2508 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002509 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002510 resultData, "app-request");
2511 Binder.restoreCallingIdentity(origId);
2512 return res;
2513 }
2514 }
2515
Dianne Hackborn860755f2010-06-03 18:47:52 -07002516 public final void finishHeavyWeightApp() {
2517 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2518 != PackageManager.PERMISSION_GRANTED) {
2519 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2520 + Binder.getCallingPid()
2521 + ", uid=" + Binder.getCallingUid()
2522 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2523 Slog.w(TAG, msg);
2524 throw new SecurityException(msg);
2525 }
2526
2527 synchronized(this) {
2528 if (mHeavyWeightProcess == null) {
2529 return;
2530 }
2531
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002532 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002533 mHeavyWeightProcess.activities);
2534 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002535 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002536 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002537 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002538 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002539 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002540 null, "finish-heavy");
2541 }
2542 }
2543 }
2544
2545 mHeavyWeightProcess = null;
2546 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2547 }
2548 }
2549
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002550 public void crashApplication(int uid, int initialPid, String packageName,
2551 String message) {
2552 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2553 != PackageManager.PERMISSION_GRANTED) {
2554 String msg = "Permission Denial: crashApplication() from pid="
2555 + Binder.getCallingPid()
2556 + ", uid=" + Binder.getCallingUid()
2557 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2558 Slog.w(TAG, msg);
2559 throw new SecurityException(msg);
2560 }
2561
2562 synchronized(this) {
2563 ProcessRecord proc = null;
2564
2565 // Figure out which process to kill. We don't trust that initialPid
2566 // still has any relation to current pids, so must scan through the
2567 // list.
2568 synchronized (mPidsSelfLocked) {
2569 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2570 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2571 if (p.info.uid != uid) {
2572 continue;
2573 }
2574 if (p.pid == initialPid) {
2575 proc = p;
2576 break;
2577 }
2578 for (String str : p.pkgList) {
2579 if (str.equals(packageName)) {
2580 proc = p;
2581 }
2582 }
2583 }
2584 }
2585
2586 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002587 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002588 + " initialPid=" + initialPid
2589 + " packageName=" + packageName);
2590 return;
2591 }
2592
2593 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002594 if (proc.pid == Process.myPid()) {
2595 Log.w(TAG, "crashApplication: trying to crash self!");
2596 return;
2597 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002598 long ident = Binder.clearCallingIdentity();
2599 try {
2600 proc.thread.scheduleCrash(message);
2601 } catch (RemoteException e) {
2602 }
2603 Binder.restoreCallingIdentity(ident);
2604 }
2605 }
2606 }
2607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002608 public final void finishSubActivity(IBinder token, String resultWho,
2609 int requestCode) {
2610 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002611 ActivityRecord self = mMainStack.isInStackLocked(token);
2612 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 return;
2614 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002615
2616 final long origId = Binder.clearCallingIdentity();
2617
2618 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002619 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2620 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 if (r.resultTo == self && r.requestCode == requestCode) {
2622 if ((r.resultWho == null && resultWho == null) ||
2623 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002624 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002625 Activity.RESULT_CANCELED, null, "request-sub");
2626 }
2627 }
2628 }
2629
2630 Binder.restoreCallingIdentity(origId);
2631 }
2632 }
2633
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002634 public boolean willActivityBeVisible(IBinder token) {
2635 synchronized(this) {
2636 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002637 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2638 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002639 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002640 return true;
2641 }
2642 if (r.fullscreen && !r.finishing) {
2643 return false;
2644 }
2645 }
2646 return true;
2647 }
2648 }
2649
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002650 public void overridePendingTransition(IBinder token, String packageName,
2651 int enterAnim, int exitAnim) {
2652 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002653 ActivityRecord self = mMainStack.isInStackLocked(token);
2654 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002655 return;
2656 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002657
2658 final long origId = Binder.clearCallingIdentity();
2659
2660 if (self.state == ActivityState.RESUMED
2661 || self.state == ActivityState.PAUSING) {
2662 mWindowManager.overridePendingAppTransition(packageName,
2663 enterAnim, exitAnim);
2664 }
2665
2666 Binder.restoreCallingIdentity(origId);
2667 }
2668 }
2669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002670 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002671 * Main function for removing an existing process from the activity manager
2672 * as a result of that process going away. Clears out all connections
2673 * to the process.
2674 */
2675 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002676 boolean restarting, boolean allowRestart) {
2677 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002679 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002680 }
2681
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002682 if (mProfileProc == app) {
2683 clearProfilerLocked();
2684 }
2685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002687 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2688 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2689 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002690 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002691 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2692 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002693 }
2694
2695 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002696 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697
2698 boolean atTop = true;
2699 boolean hasVisibleActivities = false;
2700
2701 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002702 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002703 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002704 TAG, "Removing app " + app + " from history with " + i + " entries");
2705 while (i > 0) {
2706 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002707 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002708 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2710 if (r.app == app) {
2711 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002712 if (ActivityStack.DEBUG_ADD_REMOVE) {
2713 RuntimeException here = new RuntimeException("here");
2714 here.fillInStackTrace();
2715 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2716 + ": haveState=" + r.haveState
2717 + " stateNotNeeded=" + r.stateNotNeeded
2718 + " finishing=" + r.finishing
2719 + " state=" + r.state, here);
2720 }
2721 if (!r.finishing) {
2722 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -08002723 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2724 System.identityHashCode(r),
2725 r.task.taskId, r.shortComponentName,
2726 "proc died without state saved");
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002727 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002728 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002729 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002730 r.takeFromHistory();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002731 mWindowManager.removeAppToken(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002732 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002733 mMainStack.validateAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002734 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002735 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002736
2737 } else {
2738 // We have the current state for this activity, so
2739 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002740 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002741 TAG, "Keeping entry, setting app to null");
2742 if (r.visible) {
2743 hasVisibleActivities = true;
2744 }
2745 r.app = null;
2746 r.nowVisible = false;
2747 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002748 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2749 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002750 r.icicle = null;
2751 }
2752 }
2753
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002754 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002755 }
2756 atTop = false;
2757 }
2758
2759 app.activities.clear();
2760
2761 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002762 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002763 + " running instrumentation " + app.instrumentationClass);
2764 Bundle info = new Bundle();
2765 info.putString("shortMsg", "Process crashed.");
2766 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2767 }
2768
2769 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002770 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002771 // If there was nothing to resume, and we are not already
2772 // restarting this process, but there is a visible activity that
2773 // is hosted by the process... then make sure all visible
2774 // activities are running, taking care of restarting this
2775 // process.
2776 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002777 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778 }
2779 }
2780 }
2781 }
2782
2783 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2784 IBinder threadBinder = thread.asBinder();
2785
2786 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002787 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2788 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002789 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2790 return i;
2791 }
2792 }
2793 return -1;
2794 }
2795
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002796 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002797 IApplicationThread thread) {
2798 if (thread == null) {
2799 return null;
2800 }
2801
2802 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002803 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002804 }
2805
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002806 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002807 IApplicationThread thread) {
2808
2809 mProcDeaths[0]++;
2810
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002811 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2812 synchronized (stats) {
2813 stats.noteProcessDiedLocked(app.info.uid, pid);
2814 }
2815
Magnus Edlund7bb25812010-02-24 15:45:06 +01002816 // Clean up already done if the process has been re-started.
2817 if (app.pid == pid && app.thread != null &&
2818 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002819 if (!app.killedBackground) {
2820 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2821 + ") has died.");
2822 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002823 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002824 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002825 TAG, "Dying app: " + app + ", pid: " + pid
2826 + ", thread: " + thread.asBinder());
2827 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002828 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002829
2830 if (doLowMem) {
2831 // If there are no longer any background processes running,
2832 // and the app that died was not running instrumentation,
2833 // then tell everyone we are now low on memory.
2834 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002835 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2836 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002837 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 haveBg = true;
2839 break;
2840 }
2841 }
2842
2843 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002844 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002845 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002846 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2847 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002848 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002849 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2850 // The low memory report is overriding any current
2851 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002852 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002853 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002854 rec.lastRequestedGc = 0;
2855 } else {
2856 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002857 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002858 rec.reportLowMemory = true;
2859 rec.lastLowMemory = now;
2860 mProcessesToGc.remove(rec);
2861 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002862 }
2863 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002864 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002865 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002866 }
2867 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002868 } else if (app.pid != pid) {
2869 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002870 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002871 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002872 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002873 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002874 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002875 + thread.asBinder());
2876 }
2877 }
2878
Dan Egnor42471dd2010-01-07 17:25:22 -08002879 /**
2880 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002881 * @param clearTraces causes the dump file to be erased prior to the new
2882 * traces being written, if true; when false, the new traces will be
2883 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002884 * @param firstPids of dalvik VM processes to dump stack traces for first
2885 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002886 * @return file containing stack traces, or null if no dump file is configured
2887 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002888 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2889 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002890 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2891 if (tracesPath == null || tracesPath.length() == 0) {
2892 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002894
2895 File tracesFile = new File(tracesPath);
2896 try {
2897 File tracesDir = tracesFile.getParentFile();
2898 if (!tracesDir.exists()) tracesFile.mkdirs();
2899 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2900
Christopher Tate6ee412d2010-05-28 12:01:56 -07002901 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002902 tracesFile.createNewFile();
2903 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2904 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002905 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002906 return null;
2907 }
2908
2909 // Use a FileObserver to detect when traces finish writing.
2910 // The order of traces is considered important to maintain for legibility.
2911 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2912 public synchronized void onEvent(int event, String path) { notify(); }
2913 };
2914
2915 try {
2916 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002917
2918 // First collect all of the stacks of the most important pids.
2919 try {
2920 int num = firstPids.size();
2921 for (int i = 0; i < num; i++) {
2922 synchronized (observer) {
2923 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2924 observer.wait(200); // Wait for write-close, give up after 200msec
2925 }
2926 }
2927 } catch (InterruptedException e) {
2928 Log.wtf(TAG, e);
2929 }
2930
2931 // Next measure CPU usage.
2932 if (processStats != null) {
2933 processStats.init();
2934 System.gc();
2935 processStats.update();
2936 try {
2937 synchronized (processStats) {
2938 processStats.wait(500); // measure over 1/2 second.
2939 }
2940 } catch (InterruptedException e) {
2941 }
2942 processStats.update();
2943
2944 // We'll take the stack crawls of just the top apps using CPU.
2945 final int N = processStats.countWorkingStats();
2946 int numProcs = 0;
2947 for (int i=0; i<N && numProcs<5; i++) {
2948 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2949 if (lastPids.indexOfKey(stats.pid) >= 0) {
2950 numProcs++;
2951 try {
2952 synchronized (observer) {
2953 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2954 observer.wait(200); // Wait for write-close, give up after 200msec
2955 }
2956 } catch (InterruptedException e) {
2957 Log.wtf(TAG, e);
2958 }
2959
2960 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002961 }
2962 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002963
2964 return tracesFile;
2965
Dan Egnor42471dd2010-01-07 17:25:22 -08002966 } finally {
2967 observer.stopWatching();
2968 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002969 }
2970
Jeff Brown4d94a762010-09-23 11:33:28 -07002971 private final class AppNotResponding implements Runnable {
2972 private final ProcessRecord mApp;
2973 private final String mAnnotation;
2974
2975 public AppNotResponding(ProcessRecord app, String annotation) {
2976 mApp = app;
2977 mAnnotation = annotation;
2978 }
2979
2980 @Override
2981 public void run() {
2982 appNotResponding(mApp, null, null, mAnnotation);
2983 }
2984 }
2985
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002986 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2987 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002988 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2989 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2990
Dianne Hackborn287952c2010-09-22 22:34:31 -07002991 if (mController != null) {
2992 try {
2993 // 0 == continue, -1 = kill process immediately
2994 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2995 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2996 } catch (RemoteException e) {
2997 mController = null;
2998 }
2999 }
3000
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003001 long anrTime = SystemClock.uptimeMillis();
3002 if (MONITOR_CPU_USAGE) {
3003 updateCpuStatsNow();
3004 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003005
3006 synchronized (this) {
3007 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3008 if (mShuttingDown) {
3009 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3010 return;
3011 } else if (app.notResponding) {
3012 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3013 return;
3014 } else if (app.crashing) {
3015 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3016 return;
3017 }
3018
3019 // In case we come through here for the same app before completing
3020 // this one, mark as anring now so we will bail out.
3021 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003022
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003023 // Log the ANR to the event log.
3024 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3025 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003026
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003027 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003028 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003029
3030 int parentPid = app.pid;
3031 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003032 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003033
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003034 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003035
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003036 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3037 ProcessRecord r = mLruProcesses.get(i);
3038 if (r != null && r.thread != null) {
3039 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003040 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3041 if (r.persistent) {
3042 firstPids.add(pid);
3043 } else {
3044 lastPids.put(pid, Boolean.TRUE);
3045 }
3046 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003048 }
3049 }
3050
Dan Egnor42471dd2010-01-07 17:25:22 -08003051 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003052 StringBuilder info = mStringBuilder;
3053 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003054 info.append("ANR in ").append(app.processName);
3055 if (activity != null && activity.shortComponentName != null) {
3056 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003057 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003058 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003059 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003060 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003062 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003063 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003064 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003065
Dianne Hackborn287952c2010-09-22 22:34:31 -07003066 final ProcessStats processStats = new ProcessStats(true);
3067
3068 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3069
Dan Egnor42471dd2010-01-07 17:25:22 -08003070 String cpuInfo = null;
3071 if (MONITOR_CPU_USAGE) {
3072 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003073 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003074 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003075 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003076 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003077 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003078 }
3079
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003080 info.append(processStats.printCurrentState(anrTime));
3081
Joe Onorato8a9b2202010-02-26 18:56:32 -08003082 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003083 if (tracesFile == null) {
3084 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3085 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3086 }
3087
Jeff Sharkeya353d262011-10-28 11:12:06 -07003088 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3089 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003090
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003091 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003092 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003093 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3094 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003095 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003096 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3097 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003098 }
3099 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003100 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003101 }
3102 }
3103
Dan Egnor42471dd2010-01-07 17:25:22 -08003104 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3105 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3106 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003107
3108 synchronized (this) {
3109 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003110 Slog.w(TAG, "Killing " + app + ": background ANR");
3111 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3112 app.processName, app.setAdj, "background ANR");
3113 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003114 return;
3115 }
3116
3117 // Set the app's notResponding state, and look up the errorReportReceiver
3118 makeAppNotRespondingLocked(app,
3119 activity != null ? activity.shortComponentName : null,
3120 annotation != null ? "ANR " + annotation : "ANR",
3121 info.toString());
3122
3123 // Bring up the infamous App Not Responding dialog
3124 Message msg = Message.obtain();
3125 HashMap map = new HashMap();
3126 msg.what = SHOW_NOT_RESPONDING_MSG;
3127 msg.obj = map;
3128 map.put("app", app);
3129 if (activity != null) {
3130 map.put("activity", activity);
3131 }
3132
3133 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003134 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003135 }
3136
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003137 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3138 if (!mLaunchWarningShown) {
3139 mLaunchWarningShown = true;
3140 mHandler.post(new Runnable() {
3141 @Override
3142 public void run() {
3143 synchronized (ActivityManagerService.this) {
3144 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3145 d.show();
3146 mHandler.postDelayed(new Runnable() {
3147 @Override
3148 public void run() {
3149 synchronized (ActivityManagerService.this) {
3150 d.dismiss();
3151 mLaunchWarningShown = false;
3152 }
3153 }
3154 }, 4000);
3155 }
3156 }
3157 });
3158 }
3159 }
3160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003161 public boolean clearApplicationUserData(final String packageName,
3162 final IPackageDataObserver observer) {
3163 int uid = Binder.getCallingUid();
3164 int pid = Binder.getCallingPid();
3165 long callingId = Binder.clearCallingIdentity();
3166 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003167 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003168 int pkgUid = -1;
3169 synchronized(this) {
3170 try {
3171 pkgUid = pm.getPackageUid(packageName);
3172 } catch (RemoteException e) {
3173 }
3174 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003175 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003176 return false;
3177 }
3178 if (uid == pkgUid || checkComponentPermission(
3179 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003180 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003181 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003182 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003183 } else {
3184 throw new SecurityException(pid+" does not have permission:"+
3185 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3186 "for process:"+packageName);
3187 }
3188 }
3189
3190 try {
3191 //clear application user data
3192 pm.clearApplicationUserData(packageName, observer);
3193 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3194 Uri.fromParts("package", packageName, null));
3195 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003196 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3197 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003198 } catch (RemoteException e) {
3199 }
3200 } finally {
3201 Binder.restoreCallingIdentity(callingId);
3202 }
3203 return true;
3204 }
3205
Dianne Hackborn03abb812010-01-04 18:43:19 -08003206 public void killBackgroundProcesses(final String packageName) {
3207 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3208 != PackageManager.PERMISSION_GRANTED &&
3209 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3210 != PackageManager.PERMISSION_GRANTED) {
3211 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003212 + Binder.getCallingPid()
3213 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003214 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003215 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003216 throw new SecurityException(msg);
3217 }
3218
3219 long callingId = Binder.clearCallingIdentity();
3220 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003221 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003222 int pkgUid = -1;
3223 synchronized(this) {
3224 try {
3225 pkgUid = pm.getPackageUid(packageName);
3226 } catch (RemoteException e) {
3227 }
3228 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003229 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003230 return;
3231 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003232 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003233 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3234 }
3235 } finally {
3236 Binder.restoreCallingIdentity(callingId);
3237 }
3238 }
3239
3240 public void killAllBackgroundProcesses() {
3241 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3242 != PackageManager.PERMISSION_GRANTED) {
3243 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3244 + Binder.getCallingPid()
3245 + ", uid=" + Binder.getCallingUid()
3246 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3247 Slog.w(TAG, msg);
3248 throw new SecurityException(msg);
3249 }
3250
3251 long callingId = Binder.clearCallingIdentity();
3252 try {
3253 synchronized(this) {
3254 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3255 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3256 final int NA = apps.size();
3257 for (int ia=0; ia<NA; ia++) {
3258 ProcessRecord app = apps.valueAt(ia);
3259 if (app.persistent) {
3260 // we don't kill persistent processes
3261 continue;
3262 }
3263 if (app.removed) {
3264 procs.add(app);
3265 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3266 app.removed = true;
3267 procs.add(app);
3268 }
3269 }
3270 }
3271
3272 int N = procs.size();
3273 for (int i=0; i<N; i++) {
3274 removeProcessLocked(procs.get(i), false, true, "kill all background");
3275 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003276 }
3277 } finally {
3278 Binder.restoreCallingIdentity(callingId);
3279 }
3280 }
3281
3282 public void forceStopPackage(final String packageName) {
3283 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3284 != PackageManager.PERMISSION_GRANTED) {
3285 String msg = "Permission Denial: forceStopPackage() from pid="
3286 + Binder.getCallingPid()
3287 + ", uid=" + Binder.getCallingUid()
3288 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003289 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003290 throw new SecurityException(msg);
3291 }
3292
3293 long callingId = Binder.clearCallingIdentity();
3294 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003295 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003296 int pkgUid = -1;
3297 synchronized(this) {
3298 try {
3299 pkgUid = pm.getPackageUid(packageName);
3300 } catch (RemoteException e) {
3301 }
3302 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003303 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003304 return;
3305 }
3306 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003307 try {
3308 pm.setPackageStoppedState(packageName, true);
3309 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003310 } catch (IllegalArgumentException e) {
3311 Slog.w(TAG, "Failed trying to unstop package "
3312 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003313 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003314 }
3315 } finally {
3316 Binder.restoreCallingIdentity(callingId);
3317 }
3318 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003319
3320 /*
3321 * The pkg name and uid have to be specified.
3322 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3323 */
3324 public void killApplicationWithUid(String pkg, int uid) {
3325 if (pkg == null) {
3326 return;
3327 }
3328 // Make sure the uid is valid.
3329 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003330 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003331 return;
3332 }
3333 int callerUid = Binder.getCallingUid();
3334 // Only the system server can kill an application
3335 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003336 // Post an aysnc message to kill the application
3337 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3338 msg.arg1 = uid;
3339 msg.arg2 = 0;
3340 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003341 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003342 } else {
3343 throw new SecurityException(callerUid + " cannot kill pkg: " +
3344 pkg);
3345 }
3346 }
3347
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003348 public void closeSystemDialogs(String reason) {
3349 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003350 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003351 if (reason != null) {
3352 intent.putExtra("reason", reason);
3353 }
3354
3355 final int uid = Binder.getCallingUid();
3356 final long origId = Binder.clearCallingIdentity();
3357 synchronized (this) {
3358 int i = mWatchers.beginBroadcast();
3359 while (i > 0) {
3360 i--;
3361 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3362 if (w != null) {
3363 try {
3364 w.closingSystemDialogs(reason);
3365 } catch (RemoteException e) {
3366 }
3367 }
3368 }
3369 mWatchers.finishBroadcast();
3370
Dianne Hackbornffa42482009-09-23 22:20:11 -07003371 mWindowManager.closeSystemDialogs(reason);
3372
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003373 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3374 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003375 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003376 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003377 Activity.RESULT_CANCELED, null, "close-sys");
3378 }
3379 }
3380
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003381 broadcastIntentLocked(null, null, intent, null,
3382 null, 0, null, null, null, false, false, -1, uid);
3383 }
3384 Binder.restoreCallingIdentity(origId);
3385 }
3386
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003387 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003388 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003389 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3390 for (int i=pids.length-1; i>=0; i--) {
3391 infos[i] = new Debug.MemoryInfo();
3392 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003393 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003394 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003395 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003396
Dianne Hackbornb437e092011-08-05 17:50:29 -07003397 public long[] getProcessPss(int[] pids) throws RemoteException {
3398 long[] pss = new long[pids.length];
3399 for (int i=pids.length-1; i>=0; i--) {
3400 pss[i] = Debug.getPss(pids[i]);
3401 }
3402 return pss;
3403 }
3404
Christopher Tate5e1ab332009-09-01 20:32:49 -07003405 public void killApplicationProcess(String processName, int uid) {
3406 if (processName == null) {
3407 return;
3408 }
3409
3410 int callerUid = Binder.getCallingUid();
3411 // Only the system server can kill an application
3412 if (callerUid == Process.SYSTEM_UID) {
3413 synchronized (this) {
3414 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003415 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003416 try {
3417 app.thread.scheduleSuicide();
3418 } catch (RemoteException e) {
3419 // If the other end already died, then our work here is done.
3420 }
3421 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003422 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003423 + processName + " / " + uid);
3424 }
3425 }
3426 } else {
3427 throw new SecurityException(callerUid + " cannot kill app process: " +
3428 processName);
3429 }
3430 }
3431
Dianne Hackborn03abb812010-01-04 18:43:19 -08003432 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003433 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003434 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3435 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003436 if (!mProcessesReady) {
3437 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003439 intent.putExtra(Intent.EXTRA_UID, uid);
3440 broadcastIntentLocked(null, null, intent,
3441 null, null, 0, null, null, null,
3442 false, false, MY_PID, Process.SYSTEM_UID);
3443 }
3444
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003445 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003446 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003447 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003448 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003449
Dianne Hackborn03abb812010-01-04 18:43:19 -08003450 // Remove all processes this package may have touched: all with the
3451 // same UID (except for the system or root user), and all whose name
3452 // matches the package name.
3453 final String procNamePrefix = packageName + ":";
3454 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3455 final int NA = apps.size();
3456 for (int ia=0; ia<NA; ia++) {
3457 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003458 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003459 // we don't kill persistent processes
3460 continue;
3461 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003462 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003463 if (doit) {
3464 procs.add(app);
3465 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003466 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3467 || app.processName.equals(packageName)
3468 || app.processName.startsWith(procNamePrefix)) {
3469 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003470 if (!doit) {
3471 return true;
3472 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003473 app.removed = true;
3474 procs.add(app);
3475 }
3476 }
3477 }
3478 }
3479
3480 int N = procs.size();
3481 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003482 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003483 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003484 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003485 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003486
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003487 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003488 boolean callerWillRestart, boolean purgeCache, boolean doit,
3489 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003490 int i;
3491 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003493 if (uid < 0) {
3494 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003495 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003496 } catch (RemoteException e) {
3497 }
3498 }
3499
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003500 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003501 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003502
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003503 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3504 while (badApps.hasNext()) {
3505 SparseArray<Long> ba = badApps.next();
3506 if (ba.get(uid) != null) {
3507 badApps.remove();
3508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003509 }
3510 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003511
3512 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003513 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003514
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003515 TaskRecord lastTask = null;
3516 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003517 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003518 final boolean samePackage = r.packageName.equals(name);
3519 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003520 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003521 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003522 if (r.finishing) {
3523 // If this activity is just finishing, then it is not
3524 // interesting as far as something to stop.
3525 continue;
3526 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003527 return true;
3528 }
3529 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003530 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003531 if (samePackage) {
3532 if (r.app != null) {
3533 r.app.removed = true;
3534 }
3535 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003536 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003537 lastTask = r.task;
3538 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3539 null, "force-stop")) {
3540 i--;
3541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003542 }
3543 }
3544
3545 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3546 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003547 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003548 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003549 if (!doit) {
3550 return true;
3551 }
3552 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003553 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 if (service.app != null) {
3555 service.app.removed = true;
3556 }
3557 service.app = null;
3558 services.add(service);
3559 }
3560 }
3561
3562 N = services.size();
3563 for (i=0; i<N; i++) {
3564 bringDownServiceLocked(services.get(i), true);
3565 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003566
3567 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3568 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3569 if (provider.info.packageName.equals(name)
3570 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3571 if (!doit) {
3572 return true;
3573 }
3574 didSomething = true;
3575 providers.add(provider);
3576 }
3577 }
3578
3579 N = providers.size();
3580 for (i=0; i<N; i++) {
3581 removeDyingProviderLocked(null, providers.get(i));
3582 }
3583
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003584 if (doit) {
3585 if (purgeCache) {
3586 AttributeCache ac = AttributeCache.instance();
3587 if (ac != null) {
3588 ac.removePackage(name);
3589 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003590 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003591 if (mBooted) {
3592 mMainStack.resumeTopActivityLocked(null);
3593 mMainStack.scheduleIdleLocked();
3594 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003595 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003596
3597 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 }
3599
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003600 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003601 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602 final String name = app.processName;
3603 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003604 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003605 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003606 + "/" + uid + ")");
3607
3608 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003609 if (mHeavyWeightProcess == app) {
3610 mHeavyWeightProcess = null;
3611 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3612 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003613 boolean needRestart = false;
3614 if (app.pid > 0 && app.pid != MY_PID) {
3615 int pid = app.pid;
3616 synchronized (mPidsSelfLocked) {
3617 mPidsSelfLocked.remove(pid);
3618 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3619 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003620 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003621 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003622 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003623 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003624
3625 if (app.persistent) {
3626 if (!callerWillRestart) {
3627 addAppLocked(app.info);
3628 } else {
3629 needRestart = true;
3630 }
3631 }
3632 } else {
3633 mRemovedProcesses.add(app);
3634 }
3635
3636 return needRestart;
3637 }
3638
3639 private final void processStartTimedOutLocked(ProcessRecord app) {
3640 final int pid = app.pid;
3641 boolean gone = false;
3642 synchronized (mPidsSelfLocked) {
3643 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3644 if (knownApp != null && knownApp.thread == null) {
3645 mPidsSelfLocked.remove(pid);
3646 gone = true;
3647 }
3648 }
3649
3650 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003651 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003652 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003653 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003654 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003655 if (mHeavyWeightProcess == app) {
3656 mHeavyWeightProcess = null;
3657 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3658 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003659 // Take care of any launching providers waiting for this process.
3660 checkAppInLaunchingProvidersLocked(app, true);
3661 // Take care of any services that are waiting for the process.
3662 for (int i=0; i<mPendingServices.size(); i++) {
3663 ServiceRecord sr = mPendingServices.get(i);
3664 if (app.info.uid == sr.appInfo.uid
3665 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003666 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003667 mPendingServices.remove(i);
3668 i--;
3669 bringDownServiceLocked(sr, true);
3670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003671 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003672 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3673 app.processName, app.setAdj, "start timeout");
3674 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003675 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003676 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003677 try {
3678 IBackupManager bm = IBackupManager.Stub.asInterface(
3679 ServiceManager.getService(Context.BACKUP_SERVICE));
3680 bm.agentDisconnected(app.info.packageName);
3681 } catch (RemoteException e) {
3682 // Can't happen; the backup manager is local
3683 }
3684 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003685 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003686 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003687 mPendingBroadcast.state = BroadcastRecord.IDLE;
3688 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003689 mPendingBroadcast = null;
3690 scheduleBroadcastsLocked();
3691 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003693 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 }
3695 }
3696
3697 private final boolean attachApplicationLocked(IApplicationThread thread,
3698 int pid) {
3699
3700 // Find the application record that is being attached... either via
3701 // the pid if we are running in multiple processes, or just pull the
3702 // next app record if we are emulating process with anonymous threads.
3703 ProcessRecord app;
3704 if (pid != MY_PID && pid >= 0) {
3705 synchronized (mPidsSelfLocked) {
3706 app = mPidsSelfLocked.get(pid);
3707 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003708 } else {
3709 app = null;
3710 }
3711
3712 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003713 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003714 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003715 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003716 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003717 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 } else {
3719 try {
3720 thread.scheduleExit();
3721 } catch (Exception e) {
3722 // Ignore exceptions.
3723 }
3724 }
3725 return false;
3726 }
3727
3728 // If this application record is still attached to a previous
3729 // process, clean it up now.
3730 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003731 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003732 }
3733
3734 // Tell the process all about itself.
3735
Joe Onorato8a9b2202010-02-26 18:56:32 -08003736 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003737 TAG, "Binding process pid " + pid + " to record " + app);
3738
3739 String processName = app.processName;
3740 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003741 AppDeathRecipient adr = new AppDeathRecipient(
3742 app, pid, thread);
3743 thread.asBinder().linkToDeath(adr, 0);
3744 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003745 } catch (RemoteException e) {
3746 app.resetPackageList();
3747 startProcessLocked(app, "link fail", processName);
3748 return false;
3749 }
3750
Doug Zongker2bec3d42009-12-04 12:52:44 -08003751 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003752
3753 app.thread = thread;
3754 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003755 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3756 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003757 app.forcingToForeground = null;
3758 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003759 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003760 app.debugging = false;
3761
3762 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3763
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003764 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003765 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003766
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003767 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003768 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003769 }
3770
Joe Onorato8a9b2202010-02-26 18:56:32 -08003771 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003772 TAG, "New app record " + app
3773 + " thread=" + thread.asBinder() + " pid=" + pid);
3774 try {
3775 int testMode = IApplicationThread.DEBUG_OFF;
3776 if (mDebugApp != null && mDebugApp.equals(processName)) {
3777 testMode = mWaitForDebugger
3778 ? IApplicationThread.DEBUG_WAIT
3779 : IApplicationThread.DEBUG_ON;
3780 app.debugging = true;
3781 if (mDebugTransient) {
3782 mDebugApp = mOrigDebugApp;
3783 mWaitForDebugger = mOrigWaitForDebugger;
3784 }
3785 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003786 String profileFile = app.instrumentationProfileFile;
3787 ParcelFileDescriptor profileFd = null;
3788 boolean profileAutoStop = false;
3789 if (mProfileApp != null && mProfileApp.equals(processName)) {
3790 mProfileProc = app;
3791 profileFile = mProfileFile;
3792 profileFd = mProfileFd;
3793 profileAutoStop = mAutoStopProfiler;
3794 }
3795
Christopher Tate181fafa2009-05-14 11:12:14 -07003796 // If the app is being launched for restore or full backup, set it up specially
3797 boolean isRestrictedBackupMode = false;
3798 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3799 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003800 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003801 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3802 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003803
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003804 ensurePackageDexOpt(app.instrumentationInfo != null
3805 ? app.instrumentationInfo.packageName
3806 : app.info.packageName);
3807 if (app.instrumentationClass != null) {
3808 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003809 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003810 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003811 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003812 ApplicationInfo appInfo = app.instrumentationInfo != null
3813 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003814 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003815 if (profileFd != null) {
3816 profileFd = profileFd.dup();
3817 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003818 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003819 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003820 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003821 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08003822 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003823 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003824 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003825 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003826 } catch (Exception e) {
3827 // todo: Yikes! What should we do? For now we will try to
3828 // start another process, but that could easily get us in
3829 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003830 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003831
3832 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003833 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003834 startProcessLocked(app, "bind fail", processName);
3835 return false;
3836 }
3837
3838 // Remove this record from the list of starting applications.
3839 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003840 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3841 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842 mProcessesOnHold.remove(app);
3843
3844 boolean badApp = false;
3845 boolean didSomething = false;
3846
3847 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003848 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003849 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003850 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3851 && processName.equals(hr.processName)) {
3852 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003853 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003854 didSomething = true;
3855 }
3856 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003857 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003858 + hr.intent.getComponent().flattenToShortString(), e);
3859 badApp = true;
3860 }
3861 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003862 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003863 }
3864 }
3865
3866 // Find any services that should be running in this process...
3867 if (!badApp && mPendingServices.size() > 0) {
3868 ServiceRecord sr = null;
3869 try {
3870 for (int i=0; i<mPendingServices.size(); i++) {
3871 sr = mPendingServices.get(i);
3872 if (app.info.uid != sr.appInfo.uid
3873 || !processName.equals(sr.processName)) {
3874 continue;
3875 }
3876
3877 mPendingServices.remove(i);
3878 i--;
3879 realStartServiceLocked(sr, app);
3880 didSomething = true;
3881 }
3882 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003883 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003884 + sr.shortName, e);
3885 badApp = true;
3886 }
3887 }
3888
3889 // Check if the next broadcast receiver is in this process...
3890 BroadcastRecord br = mPendingBroadcast;
3891 if (!badApp && br != null && br.curApp == app) {
3892 try {
3893 mPendingBroadcast = null;
3894 processCurBroadcastLocked(br, app);
3895 didSomething = true;
3896 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003897 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003898 + br.curComponent.flattenToShortString(), e);
3899 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003900 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003901 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3902 br.resultExtras, br.resultAbort, true);
3903 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003904 // We need to reset the state if we fails to start the receiver.
3905 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003906 }
3907 }
3908
Christopher Tate181fafa2009-05-14 11:12:14 -07003909 // Check whether the next backup agent is in this process...
3910 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003911 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003912 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003913 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003914 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3915 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3916 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003917 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003918 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003919 e.printStackTrace();
3920 }
3921 }
3922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003923 if (badApp) {
3924 // todo: Also need to kill application to deal with all
3925 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003926 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003927 return false;
3928 }
3929
3930 if (!didSomething) {
3931 updateOomAdjLocked();
3932 }
3933
3934 return true;
3935 }
3936
3937 public final void attachApplication(IApplicationThread thread) {
3938 synchronized (this) {
3939 int callingPid = Binder.getCallingPid();
3940 final long origId = Binder.clearCallingIdentity();
3941 attachApplicationLocked(thread, callingPid);
3942 Binder.restoreCallingIdentity(origId);
3943 }
3944 }
3945
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003946 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003947 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003948 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3949 if (stopProfiling) {
3950 synchronized (this) {
3951 if (mProfileProc == r.app) {
3952 if (mProfileFd != null) {
3953 try {
3954 mProfileFd.close();
3955 } catch (IOException e) {
3956 }
3957 clearProfilerLocked();
3958 }
3959 }
3960 }
3961 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003962 Binder.restoreCallingIdentity(origId);
3963 }
3964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003966 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003967 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 mWindowManager.enableScreenAfterBoot();
3969 }
3970
Dianne Hackborn661cd522011-08-22 00:26:20 -07003971 public void showBootMessage(final CharSequence msg, final boolean always) {
3972 mWindowManager.showBootMessage(msg, always);
3973 }
3974
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003975 public void dismissKeyguardOnNextActivity() {
3976 synchronized (this) {
3977 mMainStack.dismissKeyguardOnNextActivityLocked();
3978 }
3979 }
3980
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003981 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003982 IntentFilter pkgFilter = new IntentFilter();
3983 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3984 pkgFilter.addDataScheme("package");
3985 mContext.registerReceiver(new BroadcastReceiver() {
3986 @Override
3987 public void onReceive(Context context, Intent intent) {
3988 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3989 if (pkgs != null) {
3990 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003991 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003992 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003993 setResultCode(Activity.RESULT_OK);
3994 return;
3995 }
3996 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003997 }
3998 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003999 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004000 }, pkgFilter);
4001
4002 synchronized (this) {
4003 // Ensure that any processes we had put on hold are now started
4004 // up.
4005 final int NP = mProcessesOnHold.size();
4006 if (NP > 0) {
4007 ArrayList<ProcessRecord> procs =
4008 new ArrayList<ProcessRecord>(mProcessesOnHold);
4009 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004010 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4011 + procs.get(ip));
4012 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004013 }
4014 }
4015
4016 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004017 // Start looking for apps that are abusing wake locks.
4018 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004019 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004020 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004021 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004022 broadcastIntentLocked(null, null,
4023 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4024 null, null, 0, null, null,
4025 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4026 false, false, MY_PID, Process.SYSTEM_UID);
4027 }
4028 }
4029 }
4030
4031 final void ensureBootCompleted() {
4032 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004033 boolean enableScreen;
4034 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004035 booting = mBooting;
4036 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004037 enableScreen = !mBooted;
4038 mBooted = true;
4039 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004040
4041 if (booting) {
4042 finishBooting();
4043 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004044
4045 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004046 enableScreenAfterBoot();
4047 }
4048 }
4049
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004050 public final void activityPaused(IBinder token) {
4051 final long origId = Binder.clearCallingIdentity();
4052 mMainStack.activityPaused(token, false);
4053 Binder.restoreCallingIdentity(origId);
4054 }
4055
4056 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4057 CharSequence description) {
4058 if (localLOGV) Slog.v(
4059 TAG, "Activity stopped: token=" + token);
4060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004061 // Refuse possible leaked file descriptors
4062 if (icicle != null && icicle.hasFileDescriptors()) {
4063 throw new IllegalArgumentException("File descriptors passed in Bundle");
4064 }
4065
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004066 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004067
4068 final long origId = Binder.clearCallingIdentity();
4069
4070 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004071 r = mMainStack.isInStackLocked(token);
4072 if (r != null) {
4073 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004074 }
4075 }
4076
4077 if (r != null) {
4078 sendPendingThumbnail(r, null, null, null, false);
4079 }
4080
4081 trimApplications();
4082
4083 Binder.restoreCallingIdentity(origId);
4084 }
4085
4086 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004087 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004088 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 }
4090
4091 public String getCallingPackage(IBinder token) {
4092 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004093 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004094 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004095 }
4096 }
4097
4098 public ComponentName getCallingActivity(IBinder token) {
4099 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004100 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004101 return r != null ? r.intent.getComponent() : null;
4102 }
4103 }
4104
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004105 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004106 ActivityRecord r = mMainStack.isInStackLocked(token);
4107 if (r == null) {
4108 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004109 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004110 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004111 }
4112
4113 public ComponentName getActivityClassForToken(IBinder token) {
4114 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004115 ActivityRecord r = mMainStack.isInStackLocked(token);
4116 if (r == null) {
4117 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004118 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004119 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004120 }
4121 }
4122
4123 public String getPackageForToken(IBinder token) {
4124 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004125 ActivityRecord r = mMainStack.isInStackLocked(token);
4126 if (r == null) {
4127 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004129 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004130 }
4131 }
4132
4133 public IIntentSender getIntentSender(int type,
4134 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004135 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004136 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004137 if (intents != null) {
4138 if (intents.length < 1) {
4139 throw new IllegalArgumentException("Intents array length must be >= 1");
4140 }
4141 for (int i=0; i<intents.length; i++) {
4142 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004143 if (intent != null) {
4144 if (intent.hasFileDescriptors()) {
4145 throw new IllegalArgumentException("File descriptors passed in Intent");
4146 }
4147 if (type == INTENT_SENDER_BROADCAST &&
4148 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4149 throw new IllegalArgumentException(
4150 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4151 }
4152 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004153 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004154 }
4155 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004156 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004157 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004158 }
4159 }
4160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004161 synchronized(this) {
4162 int callingUid = Binder.getCallingUid();
4163 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004164 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004165 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 .getPackageUid(packageName);
4167 if (uid != Binder.getCallingUid()) {
4168 String msg = "Permission Denial: getIntentSender() from pid="
4169 + Binder.getCallingPid()
4170 + ", uid=" + Binder.getCallingUid()
4171 + ", (need uid=" + uid + ")"
4172 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004173 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004174 throw new SecurityException(msg);
4175 }
4176 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004177
4178 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004179 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004181 } catch (RemoteException e) {
4182 throw new SecurityException(e);
4183 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004184 }
4185 }
4186
4187 IIntentSender getIntentSenderLocked(int type,
4188 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004189 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004190 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004191 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004192 activity = mMainStack.isInStackLocked(token);
4193 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004194 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004195 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004196 if (activity.finishing) {
4197 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004198 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004199 }
4200
4201 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4202 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4203 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4204 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4205 |PendingIntent.FLAG_UPDATE_CURRENT);
4206
4207 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4208 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004209 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004210 WeakReference<PendingIntentRecord> ref;
4211 ref = mIntentSenderRecords.get(key);
4212 PendingIntentRecord rec = ref != null ? ref.get() : null;
4213 if (rec != null) {
4214 if (!cancelCurrent) {
4215 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004216 if (rec.key.requestIntent != null) {
4217 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4218 }
4219 if (intents != null) {
4220 intents[intents.length-1] = rec.key.requestIntent;
4221 rec.key.allIntents = intents;
4222 rec.key.allResolvedTypes = resolvedTypes;
4223 } else {
4224 rec.key.allIntents = null;
4225 rec.key.allResolvedTypes = null;
4226 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004228 return rec;
4229 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004230 rec.canceled = true;
4231 mIntentSenderRecords.remove(key);
4232 }
4233 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004234 return rec;
4235 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004236 rec = new PendingIntentRecord(this, key, callingUid);
4237 mIntentSenderRecords.put(key, rec.ref);
4238 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4239 if (activity.pendingResults == null) {
4240 activity.pendingResults
4241 = new HashSet<WeakReference<PendingIntentRecord>>();
4242 }
4243 activity.pendingResults.add(rec.ref);
4244 }
4245 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004246 }
4247
4248 public void cancelIntentSender(IIntentSender sender) {
4249 if (!(sender instanceof PendingIntentRecord)) {
4250 return;
4251 }
4252 synchronized(this) {
4253 PendingIntentRecord rec = (PendingIntentRecord)sender;
4254 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004255 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004256 .getPackageUid(rec.key.packageName);
4257 if (uid != Binder.getCallingUid()) {
4258 String msg = "Permission Denial: cancelIntentSender() from pid="
4259 + Binder.getCallingPid()
4260 + ", uid=" + Binder.getCallingUid()
4261 + " is not allowed to cancel packges "
4262 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004263 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004264 throw new SecurityException(msg);
4265 }
4266 } catch (RemoteException e) {
4267 throw new SecurityException(e);
4268 }
4269 cancelIntentSenderLocked(rec, true);
4270 }
4271 }
4272
4273 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4274 rec.canceled = true;
4275 mIntentSenderRecords.remove(rec.key);
4276 if (cleanActivity && rec.key.activity != null) {
4277 rec.key.activity.pendingResults.remove(rec.ref);
4278 }
4279 }
4280
4281 public String getPackageForIntentSender(IIntentSender pendingResult) {
4282 if (!(pendingResult instanceof PendingIntentRecord)) {
4283 return null;
4284 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004285 try {
4286 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4287 return res.key.packageName;
4288 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004289 }
4290 return null;
4291 }
4292
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004293 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4294 if (!(pendingResult instanceof PendingIntentRecord)) {
4295 return false;
4296 }
4297 try {
4298 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4299 if (res.key.allIntents == null) {
4300 return false;
4301 }
4302 for (int i=0; i<res.key.allIntents.length; i++) {
4303 Intent intent = res.key.allIntents[i];
4304 if (intent.getPackage() != null && intent.getComponent() != null) {
4305 return false;
4306 }
4307 }
4308 return true;
4309 } catch (ClassCastException e) {
4310 }
4311 return false;
4312 }
4313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004314 public void setProcessLimit(int max) {
4315 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4316 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004317 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004318 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004319 mProcessLimitOverride = max;
4320 }
4321 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004322 }
4323
4324 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004325 synchronized (this) {
4326 return mProcessLimitOverride;
4327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004328 }
4329
4330 void foregroundTokenDied(ForegroundToken token) {
4331 synchronized (ActivityManagerService.this) {
4332 synchronized (mPidsSelfLocked) {
4333 ForegroundToken cur
4334 = mForegroundProcesses.get(token.pid);
4335 if (cur != token) {
4336 return;
4337 }
4338 mForegroundProcesses.remove(token.pid);
4339 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4340 if (pr == null) {
4341 return;
4342 }
4343 pr.forcingToForeground = null;
4344 pr.foregroundServices = false;
4345 }
4346 updateOomAdjLocked();
4347 }
4348 }
4349
4350 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4351 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4352 "setProcessForeground()");
4353 synchronized(this) {
4354 boolean changed = false;
4355
4356 synchronized (mPidsSelfLocked) {
4357 ProcessRecord pr = mPidsSelfLocked.get(pid);
4358 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004359 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004360 return;
4361 }
4362 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4363 if (oldToken != null) {
4364 oldToken.token.unlinkToDeath(oldToken, 0);
4365 mForegroundProcesses.remove(pid);
4366 pr.forcingToForeground = null;
4367 changed = true;
4368 }
4369 if (isForeground && token != null) {
4370 ForegroundToken newToken = new ForegroundToken() {
4371 public void binderDied() {
4372 foregroundTokenDied(this);
4373 }
4374 };
4375 newToken.pid = pid;
4376 newToken.token = token;
4377 try {
4378 token.linkToDeath(newToken, 0);
4379 mForegroundProcesses.put(pid, newToken);
4380 pr.forcingToForeground = token;
4381 changed = true;
4382 } catch (RemoteException e) {
4383 // If the process died while doing this, we will later
4384 // do the cleanup with the process death link.
4385 }
4386 }
4387 }
4388
4389 if (changed) {
4390 updateOomAdjLocked();
4391 }
4392 }
4393 }
4394
4395 // =========================================================
4396 // PERMISSIONS
4397 // =========================================================
4398
4399 static class PermissionController extends IPermissionController.Stub {
4400 ActivityManagerService mActivityManagerService;
4401 PermissionController(ActivityManagerService activityManagerService) {
4402 mActivityManagerService = activityManagerService;
4403 }
4404
4405 public boolean checkPermission(String permission, int pid, int uid) {
4406 return mActivityManagerService.checkPermission(permission, pid,
4407 uid) == PackageManager.PERMISSION_GRANTED;
4408 }
4409 }
4410
4411 /**
4412 * This can be called with or without the global lock held.
4413 */
4414 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004415 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004416 // We might be performing an operation on behalf of an indirect binder
4417 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4418 // client identity accordingly before proceeding.
4419 Identity tlsIdentity = sCallerIdentity.get();
4420 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004421 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004422 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4423 uid = tlsIdentity.uid;
4424 pid = tlsIdentity.pid;
4425 }
4426
4427 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004428 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004429 return PackageManager.PERMISSION_GRANTED;
4430 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004431 // If there is a uid that owns whatever is being accessed, it has
4432 // blanket access to it regardless of the permissions it requires.
4433 if (owningUid >= 0 && uid == owningUid) {
4434 return PackageManager.PERMISSION_GRANTED;
4435 }
4436 // If the target is not exported, then nobody else can get to it.
4437 if (!exported) {
4438 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004439 return PackageManager.PERMISSION_DENIED;
4440 }
4441 if (permission == null) {
4442 return PackageManager.PERMISSION_GRANTED;
4443 }
4444 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004445 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004446 .checkUidPermission(permission, uid);
4447 } catch (RemoteException e) {
4448 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004449 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004450 }
4451 return PackageManager.PERMISSION_DENIED;
4452 }
4453
4454 /**
4455 * As the only public entry point for permissions checking, this method
4456 * can enforce the semantic that requesting a check on a null global
4457 * permission is automatically denied. (Internally a null permission
4458 * string is used when calling {@link #checkComponentPermission} in cases
4459 * when only uid-based security is needed.)
4460 *
4461 * This can be called with or without the global lock held.
4462 */
4463 public int checkPermission(String permission, int pid, int uid) {
4464 if (permission == null) {
4465 return PackageManager.PERMISSION_DENIED;
4466 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004467 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004468 }
4469
4470 /**
4471 * Binder IPC calls go through the public entry point.
4472 * This can be called with or without the global lock held.
4473 */
4474 int checkCallingPermission(String permission) {
4475 return checkPermission(permission,
4476 Binder.getCallingPid(),
4477 Binder.getCallingUid());
4478 }
4479
4480 /**
4481 * This can be called with or without the global lock held.
4482 */
4483 void enforceCallingPermission(String permission, String func) {
4484 if (checkCallingPermission(permission)
4485 == PackageManager.PERMISSION_GRANTED) {
4486 return;
4487 }
4488
4489 String msg = "Permission Denial: " + func + " from pid="
4490 + Binder.getCallingPid()
4491 + ", uid=" + Binder.getCallingUid()
4492 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004493 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004494 throw new SecurityException(msg);
4495 }
4496
4497 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004498 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4499 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4500 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4501 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4502 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004504 // Is the component private from the target uid?
4505 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4506
4507 // Acceptable if the there is no read permission needed from the
4508 // target or the target is holding the read permission.
4509 if (!readPerm) {
4510 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004511 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004512 == PackageManager.PERMISSION_GRANTED)) {
4513 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 }
4515 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004516
4517 // Acceptable if the there is no write permission needed from the
4518 // target or the target is holding the read permission.
4519 if (!writePerm) {
4520 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004522 == PackageManager.PERMISSION_GRANTED)) {
4523 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004524 }
4525 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004526
4527 // Acceptable if there is a path permission matching the URI that
4528 // the target holds the permission on.
4529 PathPermission[] pps = pi.pathPermissions;
4530 if (pps != null && (!readPerm || !writePerm)) {
4531 final String path = uri.getPath();
4532 int i = pps.length;
4533 while (i > 0 && (!readPerm || !writePerm)) {
4534 i--;
4535 PathPermission pp = pps[i];
4536 if (!readPerm) {
4537 final String pprperm = pp.getReadPermission();
4538 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4539 + pprperm + " for " + pp.getPath()
4540 + ": match=" + pp.match(path)
4541 + " check=" + pm.checkUidPermission(pprperm, uid));
4542 if (pprperm != null && pp.match(path) &&
4543 (pm.checkUidPermission(pprperm, uid)
4544 == PackageManager.PERMISSION_GRANTED)) {
4545 readPerm = true;
4546 }
4547 }
4548 if (!writePerm) {
4549 final String ppwperm = pp.getWritePermission();
4550 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4551 + ppwperm + " for " + pp.getPath()
4552 + ": match=" + pp.match(path)
4553 + " check=" + pm.checkUidPermission(ppwperm, uid));
4554 if (ppwperm != null && pp.match(path) &&
4555 (pm.checkUidPermission(ppwperm, uid)
4556 == PackageManager.PERMISSION_GRANTED)) {
4557 writePerm = true;
4558 }
4559 }
4560 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004561 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004562 } catch (RemoteException e) {
4563 return false;
4564 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004565
4566 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004567 }
4568
4569 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4570 int modeFlags) {
4571 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004572 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004573 return true;
4574 }
4575 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4576 if (perms == null) return false;
4577 UriPermission perm = perms.get(uri);
4578 if (perm == null) return false;
4579 return (modeFlags&perm.modeFlags) == modeFlags;
4580 }
4581
4582 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4583 // Another redirected-binder-call permissions check as in
4584 // {@link checkComponentPermission}.
4585 Identity tlsIdentity = sCallerIdentity.get();
4586 if (tlsIdentity != null) {
4587 uid = tlsIdentity.uid;
4588 pid = tlsIdentity.pid;
4589 }
4590
4591 // Our own process gets to do everything.
4592 if (pid == MY_PID) {
4593 return PackageManager.PERMISSION_GRANTED;
4594 }
4595 synchronized(this) {
4596 return checkUriPermissionLocked(uri, uid, modeFlags)
4597 ? PackageManager.PERMISSION_GRANTED
4598 : PackageManager.PERMISSION_DENIED;
4599 }
4600 }
4601
Dianne Hackborn39792d22010-08-19 18:01:52 -07004602 /**
4603 * Check if the targetPkg can be granted permission to access uri by
4604 * the callingUid using the given modeFlags. Throws a security exception
4605 * if callingUid is not allowed to do this. Returns the uid of the target
4606 * if the URI permission grant should be performed; returns -1 if it is not
4607 * needed (for example targetPkg already has permission to access the URI).
4608 */
4609 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4610 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4612 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4613 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004614 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004615 }
4616
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004617 if (targetPkg != null) {
4618 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4619 "Checking grant " + targetPkg + " permission to " + uri);
4620 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004621
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004622 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004623
4624 // If this is not a content: uri, we can't do anything with it.
4625 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004626 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004627 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004628 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 }
4630
4631 String name = uri.getAuthority();
4632 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004633 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 if (cpr != null) {
4635 pi = cpr.info;
4636 } else {
4637 try {
4638 pi = pm.resolveContentProvider(name,
4639 PackageManager.GET_URI_PERMISSION_PATTERNS);
4640 } catch (RemoteException ex) {
4641 }
4642 }
4643 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004644 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004645 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004646 }
4647
4648 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004649 if (targetPkg != null) {
4650 try {
4651 targetUid = pm.getPackageUid(targetPkg);
4652 if (targetUid < 0) {
4653 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4654 "Can't grant URI permission no uid for: " + targetPkg);
4655 return -1;
4656 }
4657 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004658 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004659 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004660 } else {
4661 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004662 }
4663
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004664 if (targetUid >= 0) {
4665 // First... does the target actually need this permission?
4666 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4667 // No need to grant the target this permission.
4668 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4669 "Target " + targetPkg + " already has full permission to " + uri);
4670 return -1;
4671 }
4672 } else {
4673 // First... there is no target package, so can anyone access it?
4674 boolean allowed = pi.exported;
4675 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4676 if (pi.readPermission != null) {
4677 allowed = false;
4678 }
4679 }
4680 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4681 if (pi.writePermission != null) {
4682 allowed = false;
4683 }
4684 }
4685 if (allowed) {
4686 return -1;
4687 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004688 }
4689
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004690 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004691 if (!pi.grantUriPermissions) {
4692 throw new SecurityException("Provider " + pi.packageName
4693 + "/" + pi.name
4694 + " does not allow granting of Uri permissions (uri "
4695 + uri + ")");
4696 }
4697 if (pi.uriPermissionPatterns != null) {
4698 final int N = pi.uriPermissionPatterns.length;
4699 boolean allowed = false;
4700 for (int i=0; i<N; i++) {
4701 if (pi.uriPermissionPatterns[i] != null
4702 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4703 allowed = true;
4704 break;
4705 }
4706 }
4707 if (!allowed) {
4708 throw new SecurityException("Provider " + pi.packageName
4709 + "/" + pi.name
4710 + " does not allow granting of permission to path of Uri "
4711 + uri);
4712 }
4713 }
4714
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004715 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004716 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004717 if (callingUid != Process.myUid()) {
4718 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4719 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4720 throw new SecurityException("Uid " + callingUid
4721 + " does not have permission to uri " + uri);
4722 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004723 }
4724 }
4725
Dianne Hackborn39792d22010-08-19 18:01:52 -07004726 return targetUid;
4727 }
4728
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004729 public int checkGrantUriPermission(int callingUid, String targetPkg,
4730 Uri uri, int modeFlags) {
4731 synchronized(this) {
4732 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4733 }
4734 }
4735
Dianne Hackborn39792d22010-08-19 18:01:52 -07004736 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4737 Uri uri, int modeFlags, UriPermissionOwner owner) {
4738 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4739 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4740 if (modeFlags == 0) {
4741 return;
4742 }
4743
4744 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004745 // to the uri, and the target doesn't. Let's now give this to
4746 // the target.
4747
Joe Onorato8a9b2202010-02-26 18:56:32 -08004748 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004749 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 HashMap<Uri, UriPermission> targetUris
4752 = mGrantedUriPermissions.get(targetUid);
4753 if (targetUris == null) {
4754 targetUris = new HashMap<Uri, UriPermission>();
4755 mGrantedUriPermissions.put(targetUid, targetUris);
4756 }
4757
4758 UriPermission perm = targetUris.get(uri);
4759 if (perm == null) {
4760 perm = new UriPermission(targetUid, uri);
4761 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004764 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004765 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004766 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004767 } else {
4768 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4769 perm.readOwners.add(owner);
4770 owner.addReadPermission(perm);
4771 }
4772 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4773 perm.writeOwners.add(owner);
4774 owner.addWritePermission(perm);
4775 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004776 }
4777 }
4778
Dianne Hackborn39792d22010-08-19 18:01:52 -07004779 void grantUriPermissionLocked(int callingUid,
4780 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004781 if (targetPkg == null) {
4782 throw new NullPointerException("targetPkg");
4783 }
4784
Dianne Hackborn39792d22010-08-19 18:01:52 -07004785 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4786 if (targetUid < 0) {
4787 return;
4788 }
4789
4790 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4791 }
4792
4793 /**
4794 * Like checkGrantUriPermissionLocked, but takes an Intent.
4795 */
4796 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4797 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004798 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004799 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004800 + " from " + intent + "; flags=0x"
4801 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4802
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004803 if (targetPkg == null) {
4804 throw new NullPointerException("targetPkg");
4805 }
4806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004807 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004808 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004809 }
4810 Uri data = intent.getData();
4811 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004812 return -1;
4813 }
4814 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4815 intent.getFlags());
4816 }
4817
4818 /**
4819 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4820 */
4821 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4822 String targetPkg, Intent intent, UriPermissionOwner owner) {
4823 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4824 intent.getFlags(), owner);
4825 }
4826
4827 void grantUriPermissionFromIntentLocked(int callingUid,
4828 String targetPkg, Intent intent, UriPermissionOwner owner) {
4829 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4830 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004831 return;
4832 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004833
4834 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004835 }
4836
4837 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4838 Uri uri, int modeFlags) {
4839 synchronized(this) {
4840 final ProcessRecord r = getRecordForAppLocked(caller);
4841 if (r == null) {
4842 throw new SecurityException("Unable to find app for caller "
4843 + caller
4844 + " when granting permission to uri " + uri);
4845 }
4846 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004847 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004848 }
4849 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004850 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004851 }
4852
4853 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4854 null);
4855 }
4856 }
4857
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004858 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004859 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4860 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4861 HashMap<Uri, UriPermission> perms
4862 = mGrantedUriPermissions.get(perm.uid);
4863 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004864 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004865 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004866 perms.remove(perm.uri);
4867 if (perms.size() == 0) {
4868 mGrantedUriPermissions.remove(perm.uid);
4869 }
4870 }
4871 }
4872 }
4873
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004874 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4875 int modeFlags) {
4876 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4877 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4878 if (modeFlags == 0) {
4879 return;
4880 }
4881
Joe Onorato8a9b2202010-02-26 18:56:32 -08004882 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004883 "Revoking all granted permissions to " + uri);
4884
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004885 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004886
4887 final String authority = uri.getAuthority();
4888 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004889 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004890 if (cpr != null) {
4891 pi = cpr.info;
4892 } else {
4893 try {
4894 pi = pm.resolveContentProvider(authority,
4895 PackageManager.GET_URI_PERMISSION_PATTERNS);
4896 } catch (RemoteException ex) {
4897 }
4898 }
4899 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004900 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004901 return;
4902 }
4903
4904 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004905 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004906 // Right now, if you are not the original owner of the permission,
4907 // you are not allowed to revoke it.
4908 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4909 throw new SecurityException("Uid " + callingUid
4910 + " does not have permission to uri " + uri);
4911 //}
4912 }
4913
4914 // Go through all of the permissions and remove any that match.
4915 final List<String> SEGMENTS = uri.getPathSegments();
4916 if (SEGMENTS != null) {
4917 final int NS = SEGMENTS.size();
4918 int N = mGrantedUriPermissions.size();
4919 for (int i=0; i<N; i++) {
4920 HashMap<Uri, UriPermission> perms
4921 = mGrantedUriPermissions.valueAt(i);
4922 Iterator<UriPermission> it = perms.values().iterator();
4923 toploop:
4924 while (it.hasNext()) {
4925 UriPermission perm = it.next();
4926 Uri targetUri = perm.uri;
4927 if (!authority.equals(targetUri.getAuthority())) {
4928 continue;
4929 }
4930 List<String> targetSegments = targetUri.getPathSegments();
4931 if (targetSegments == null) {
4932 continue;
4933 }
4934 if (targetSegments.size() < NS) {
4935 continue;
4936 }
4937 for (int j=0; j<NS; j++) {
4938 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4939 continue toploop;
4940 }
4941 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004942 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004943 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004944 perm.clearModes(modeFlags);
4945 if (perm.modeFlags == 0) {
4946 it.remove();
4947 }
4948 }
4949 if (perms.size() == 0) {
4950 mGrantedUriPermissions.remove(
4951 mGrantedUriPermissions.keyAt(i));
4952 N--;
4953 i--;
4954 }
4955 }
4956 }
4957 }
4958
4959 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4960 int modeFlags) {
4961 synchronized(this) {
4962 final ProcessRecord r = getRecordForAppLocked(caller);
4963 if (r == null) {
4964 throw new SecurityException("Unable to find app for caller "
4965 + caller
4966 + " when revoking permission to uri " + uri);
4967 }
4968 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004969 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004970 return;
4971 }
4972
4973 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4974 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4975 if (modeFlags == 0) {
4976 return;
4977 }
4978
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004979 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004980
4981 final String authority = uri.getAuthority();
4982 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004983 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004984 if (cpr != null) {
4985 pi = cpr.info;
4986 } else {
4987 try {
4988 pi = pm.resolveContentProvider(authority,
4989 PackageManager.GET_URI_PERMISSION_PATTERNS);
4990 } catch (RemoteException ex) {
4991 }
4992 }
4993 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004994 Slog.w(TAG, "No content provider found for permission revoke: "
4995 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004996 return;
4997 }
4998
4999 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
5000 }
5001 }
5002
Dianne Hackborn7e269642010-08-25 19:50:20 -07005003 @Override
5004 public IBinder newUriPermissionOwner(String name) {
5005 synchronized(this) {
5006 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5007 return owner.getExternalTokenLocked();
5008 }
5009 }
5010
5011 @Override
5012 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5013 Uri uri, int modeFlags) {
5014 synchronized(this) {
5015 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5016 if (owner == null) {
5017 throw new IllegalArgumentException("Unknown owner: " + token);
5018 }
5019 if (fromUid != Binder.getCallingUid()) {
5020 if (Binder.getCallingUid() != Process.myUid()) {
5021 // Only system code can grant URI permissions on behalf
5022 // of other users.
5023 throw new SecurityException("nice try");
5024 }
5025 }
5026 if (targetPkg == null) {
5027 throw new IllegalArgumentException("null target");
5028 }
5029 if (uri == null) {
5030 throw new IllegalArgumentException("null uri");
5031 }
5032
5033 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5034 }
5035 }
5036
5037 @Override
5038 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5039 synchronized(this) {
5040 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5041 if (owner == null) {
5042 throw new IllegalArgumentException("Unknown owner: " + token);
5043 }
5044
5045 if (uri == null) {
5046 owner.removeUriPermissionsLocked(mode);
5047 } else {
5048 owner.removeUriPermissionLocked(uri, mode);
5049 }
5050 }
5051 }
5052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005053 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5054 synchronized (this) {
5055 ProcessRecord app =
5056 who != null ? getRecordForAppLocked(who) : null;
5057 if (app == null) return;
5058
5059 Message msg = Message.obtain();
5060 msg.what = WAIT_FOR_DEBUGGER_MSG;
5061 msg.obj = app;
5062 msg.arg1 = waiting ? 1 : 0;
5063 mHandler.sendMessage(msg);
5064 }
5065 }
5066
5067 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005068 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5069 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005070 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005071 outInfo.threshold = homeAppMem;
5072 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5073 outInfo.hiddenAppThreshold = hiddenAppMem;
5074 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005075 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005076 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5077 ProcessList.VISIBLE_APP_ADJ);
5078 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5079 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005080 }
5081
5082 // =========================================================
5083 // TASK MANAGEMENT
5084 // =========================================================
5085
5086 public List getTasks(int maxNum, int flags,
5087 IThumbnailReceiver receiver) {
5088 ArrayList list = new ArrayList();
5089
5090 PendingThumbnailsRecord pending = null;
5091 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005092 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005093
5094 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005095 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005096 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5097 + ", receiver=" + receiver);
5098
5099 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5100 != PackageManager.PERMISSION_GRANTED) {
5101 if (receiver != null) {
5102 // If the caller wants to wait for pending thumbnails,
5103 // it ain't gonna get them.
5104 try {
5105 receiver.finished();
5106 } catch (RemoteException ex) {
5107 }
5108 }
5109 String msg = "Permission Denial: getTasks() from pid="
5110 + Binder.getCallingPid()
5111 + ", uid=" + Binder.getCallingUid()
5112 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005113 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005114 throw new SecurityException(msg);
5115 }
5116
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005117 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005118 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005119 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005120 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005121 TaskRecord curTask = null;
5122 int numActivities = 0;
5123 int numRunning = 0;
5124 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005125 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005127 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005128
5129 // Initialize state for next task if needed.
5130 if (top == null ||
5131 (top.state == ActivityState.INITIALIZING
5132 && top.task == r.task)) {
5133 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005134 curTask = r.task;
5135 numActivities = numRunning = 0;
5136 }
5137
5138 // Add 'r' into the current task.
5139 numActivities++;
5140 if (r.app != null && r.app.thread != null) {
5141 numRunning++;
5142 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005143
Joe Onorato8a9b2202010-02-26 18:56:32 -08005144 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005145 TAG, r.intent.getComponent().flattenToShortString()
5146 + ": task=" + r.task);
5147
5148 // If the next one is a different task, generate a new
5149 // TaskInfo entry for what we have.
5150 if (next == null || next.task != curTask) {
5151 ActivityManager.RunningTaskInfo ci
5152 = new ActivityManager.RunningTaskInfo();
5153 ci.id = curTask.taskId;
5154 ci.baseActivity = r.intent.getComponent();
5155 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005156 if (top.thumbHolder != null) {
5157 ci.description = top.thumbHolder.lastDescription;
5158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005159 ci.numActivities = numActivities;
5160 ci.numRunning = numRunning;
5161 //System.out.println(
5162 // "#" + maxNum + ": " + " descr=" + ci.description);
5163 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005164 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005165 TAG, "State=" + top.state + "Idle=" + top.idle
5166 + " app=" + top.app
5167 + " thr=" + (top.app != null ? top.app.thread : null));
5168 if (top.state == ActivityState.RESUMED
5169 || top.state == ActivityState.PAUSING) {
5170 if (top.idle && top.app != null
5171 && top.app.thread != null) {
5172 topRecord = top;
5173 topThumbnail = top.app.thread;
5174 } else {
5175 top.thumbnailNeeded = true;
5176 }
5177 }
5178 if (pending == null) {
5179 pending = new PendingThumbnailsRecord(receiver);
5180 }
5181 pending.pendingRecords.add(top);
5182 }
5183 list.add(ci);
5184 maxNum--;
5185 top = null;
5186 }
5187 }
5188
5189 if (pending != null) {
5190 mPendingThumbnails.add(pending);
5191 }
5192 }
5193
Joe Onorato8a9b2202010-02-26 18:56:32 -08005194 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005195
5196 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005197 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005198 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08005199 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005200 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005201 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005202 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005203 }
5204 }
5205
5206 if (pending == null && receiver != null) {
5207 // In this case all thumbnails were available and the client
5208 // is being asked to be told when the remaining ones come in...
5209 // which is unusually, since the top-most currently running
5210 // activity should never have a canned thumbnail! Oh well.
5211 try {
5212 receiver.finished();
5213 } catch (RemoteException ex) {
5214 }
5215 }
5216
5217 return list;
5218 }
5219
5220 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5221 int flags) {
5222 synchronized (this) {
5223 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5224 "getRecentTasks()");
5225
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005226 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005228 final int N = mRecentTasks.size();
5229 ArrayList<ActivityManager.RecentTaskInfo> res
5230 = new ArrayList<ActivityManager.RecentTaskInfo>(
5231 maxNum < N ? maxNum : N);
5232 for (int i=0; i<N && maxNum > 0; i++) {
5233 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005234 // Return the entry if desired by the caller. We always return
5235 // the first entry, because callers always expect this to be the
5236 // forground app. We may filter others if the caller has
5237 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5238 // we should exclude the entry.
5239 if (i == 0
5240 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005241 || (tr.intent == null)
5242 || ((tr.intent.getFlags()
5243 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5244 ActivityManager.RecentTaskInfo rti
5245 = new ActivityManager.RecentTaskInfo();
5246 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005247 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005248 rti.baseIntent = new Intent(
5249 tr.intent != null ? tr.intent : tr.affinityIntent);
5250 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005251 rti.description = tr.lastDescription;
5252
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005253 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5254 // Check whether this activity is currently available.
5255 try {
5256 if (rti.origActivity != null) {
5257 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5258 continue;
5259 }
5260 } else if (rti.baseIntent != null) {
5261 if (pm.queryIntentActivities(rti.baseIntent,
5262 null, 0) == null) {
5263 continue;
5264 }
5265 }
5266 } catch (RemoteException e) {
5267 // Will never happen.
5268 }
5269 }
5270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005271 res.add(rti);
5272 maxNum--;
5273 }
5274 }
5275 return res;
5276 }
5277 }
5278
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005279 private TaskRecord taskForIdLocked(int id) {
5280 final int N = mRecentTasks.size();
5281 for (int i=0; i<N; i++) {
5282 TaskRecord tr = mRecentTasks.get(i);
5283 if (tr.taskId == id) {
5284 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005285 }
5286 }
5287 return null;
5288 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005289
5290 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5291 synchronized (this) {
5292 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5293 "getTaskThumbnails()");
5294 TaskRecord tr = taskForIdLocked(id);
5295 if (tr != null) {
5296 return mMainStack.getTaskThumbnailsLocked(tr);
5297 }
5298 }
5299 return null;
5300 }
5301
5302 public boolean removeSubTask(int taskId, int subTaskIndex) {
5303 synchronized (this) {
5304 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5305 "removeSubTask()");
5306 long ident = Binder.clearCallingIdentity();
5307 try {
5308 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5309 } finally {
5310 Binder.restoreCallingIdentity(ident);
5311 }
5312 }
5313 }
5314
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005315 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005316 TaskRecord tr = root.task;
5317 Intent baseIntent = new Intent(
5318 tr.intent != null ? tr.intent : tr.affinityIntent);
5319 ComponentName component = baseIntent.getComponent();
5320 if (component == null) {
5321 Slog.w(TAG, "Now component for base intent of task: " + tr);
5322 return;
5323 }
5324
5325 // Find any running services associated with this app.
5326 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5327 for (ServiceRecord sr : mServices.values()) {
5328 if (sr.packageName.equals(component.getPackageName())) {
5329 services.add(sr);
5330 }
5331 }
5332
5333 // Take care of any running services associated with the app.
5334 for (int i=0; i<services.size(); i++) {
5335 ServiceRecord sr = services.get(i);
5336 if (sr.startRequested) {
5337 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005338 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005339 stopServiceLocked(sr);
5340 } else {
5341 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5342 sr.makeNextStartId(), baseIntent, -1));
5343 if (sr.app != null && sr.app.thread != null) {
5344 sendServiceArgsLocked(sr, false);
5345 }
5346 }
5347 }
5348 }
5349
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005350 if (killProcesses) {
5351 // Find any running processes associated with this app.
5352 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5353 SparseArray<ProcessRecord> appProcs
5354 = mProcessNames.getMap().get(component.getPackageName());
5355 if (appProcs != null) {
5356 for (int i=0; i<appProcs.size(); i++) {
5357 procs.add(appProcs.valueAt(i));
5358 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005359 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005360
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005361 // Kill the running processes.
5362 for (int i=0; i<procs.size(); i++) {
5363 ProcessRecord pr = procs.get(i);
5364 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5365 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5366 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5367 pr.processName, pr.setAdj, "remove task");
5368 Process.killProcessQuiet(pr.pid);
5369 } else {
5370 pr.waitingToKill = "remove task";
5371 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005372 }
5373 }
5374 }
5375
5376 public boolean removeTask(int taskId, int flags) {
5377 synchronized (this) {
5378 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5379 "removeTask()");
5380 long ident = Binder.clearCallingIdentity();
5381 try {
5382 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5383 if (r != null) {
5384 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005385 cleanUpRemovedTaskLocked(r,
5386 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005387 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005388 } else {
5389 TaskRecord tr = null;
5390 int i=0;
5391 while (i < mRecentTasks.size()) {
5392 TaskRecord t = mRecentTasks.get(i);
5393 if (t.taskId == taskId) {
5394 tr = t;
5395 break;
5396 }
5397 i++;
5398 }
5399 if (tr != null) {
5400 if (tr.numActivities <= 0) {
5401 // Caller is just removing a recent task that is
5402 // not actively running. That is easy!
5403 mRecentTasks.remove(i);
5404 } else {
5405 Slog.w(TAG, "removeTask: task " + taskId
5406 + " does not have activities to remove, "
5407 + " but numActivities=" + tr.numActivities
5408 + ": " + tr);
5409 }
5410 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005411 }
5412 } finally {
5413 Binder.restoreCallingIdentity(ident);
5414 }
5415 }
5416 return false;
5417 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005419 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5420 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005421 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005422 TaskRecord jt = startTask;
5423
5424 // First look backwards
5425 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005426 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005427 if (r.task != jt) {
5428 jt = r.task;
5429 if (affinity.equals(jt.affinity)) {
5430 return j;
5431 }
5432 }
5433 }
5434
5435 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005436 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005437 jt = startTask;
5438 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005439 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005440 if (r.task != jt) {
5441 if (affinity.equals(jt.affinity)) {
5442 return j;
5443 }
5444 jt = r.task;
5445 }
5446 }
5447
5448 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005449 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005450 return N-1;
5451 }
5452
5453 return -1;
5454 }
5455
5456 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005457 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005458 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005459 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005460 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5461 "moveTaskToFront()");
5462
5463 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005464 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5465 Binder.getCallingUid(), "Task to front")) {
5466 return;
5467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005468 final long origId = Binder.clearCallingIdentity();
5469 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005470 TaskRecord tr = taskForIdLocked(task);
5471 if (tr != null) {
5472 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5473 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005474 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005475 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5476 // Caller wants the home activity moved with it. To accomplish this,
5477 // we'll just move the home task to the top first.
5478 mMainStack.moveHomeToFrontLocked();
5479 }
5480 mMainStack.moveTaskToFrontLocked(tr, null);
5481 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005482 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005483 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5484 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005485 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005486 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5487 mMainStack.mUserLeaving = true;
5488 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005489 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5490 // Caller wants the home activity moved with it. To accomplish this,
5491 // we'll just move the home task to the top first.
5492 mMainStack.moveHomeToFrontLocked();
5493 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005494 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005495 return;
5496 }
5497 }
5498 } finally {
5499 Binder.restoreCallingIdentity(origId);
5500 }
5501 }
5502 }
5503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005504 public void moveTaskToBack(int task) {
5505 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5506 "moveTaskToBack()");
5507
5508 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005509 if (mMainStack.mResumedActivity != null
5510 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005511 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5512 Binder.getCallingUid(), "Task to back")) {
5513 return;
5514 }
5515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005516 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005517 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005518 Binder.restoreCallingIdentity(origId);
5519 }
5520 }
5521
5522 /**
5523 * Moves an activity, and all of the other activities within the same task, to the bottom
5524 * of the history stack. The activity's order within the task is unchanged.
5525 *
5526 * @param token A reference to the activity we wish to move
5527 * @param nonRoot If false then this only works if the activity is the root
5528 * of a task; if true it will work for any activity in a task.
5529 * @return Returns true if the move completed, false if not.
5530 */
5531 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5532 synchronized(this) {
5533 final long origId = Binder.clearCallingIdentity();
5534 int taskId = getTaskForActivityLocked(token, !nonRoot);
5535 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005536 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005537 }
5538 Binder.restoreCallingIdentity(origId);
5539 }
5540 return false;
5541 }
5542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005543 public void moveTaskBackwards(int task) {
5544 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5545 "moveTaskBackwards()");
5546
5547 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005548 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5549 Binder.getCallingUid(), "Task backwards")) {
5550 return;
5551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005552 final long origId = Binder.clearCallingIdentity();
5553 moveTaskBackwardsLocked(task);
5554 Binder.restoreCallingIdentity(origId);
5555 }
5556 }
5557
5558 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005559 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005560 }
5561
5562 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5563 synchronized(this) {
5564 return getTaskForActivityLocked(token, onlyRoot);
5565 }
5566 }
5567
5568 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005569 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005570 TaskRecord lastTask = null;
5571 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005572 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005573 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005574 if (!onlyRoot || lastTask != r.task) {
5575 return r.task.taskId;
5576 }
5577 return -1;
5578 }
5579 lastTask = r.task;
5580 }
5581
5582 return -1;
5583 }
5584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005585 public void finishOtherInstances(IBinder token, ComponentName className) {
5586 synchronized(this) {
5587 final long origId = Binder.clearCallingIdentity();
5588
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005589 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005590 TaskRecord lastTask = null;
5591 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005592 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005593 if (r.realActivity.equals(className)
Dianne Hackbornbe707852011-11-11 14:32:10 -08005594 && r.appToken != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005595 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005596 null, "others")) {
5597 i--;
5598 N--;
5599 }
5600 }
5601 lastTask = r.task;
5602 }
5603
5604 Binder.restoreCallingIdentity(origId);
5605 }
5606 }
5607
5608 // =========================================================
5609 // THUMBNAILS
5610 // =========================================================
5611
5612 public void reportThumbnail(IBinder token,
5613 Bitmap thumbnail, CharSequence description) {
5614 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5615 final long origId = Binder.clearCallingIdentity();
5616 sendPendingThumbnail(null, token, thumbnail, description, true);
5617 Binder.restoreCallingIdentity(origId);
5618 }
5619
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005620 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005621 Bitmap thumbnail, CharSequence description, boolean always) {
5622 TaskRecord task = null;
5623 ArrayList receivers = null;
5624
5625 //System.out.println("Send pending thumbnail: " + r);
5626
5627 synchronized(this) {
5628 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005629 r = mMainStack.isInStackLocked(token);
5630 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005631 return;
5632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005633 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005634 if (thumbnail == null && r.thumbHolder != null) {
5635 thumbnail = r.thumbHolder.lastThumbnail;
5636 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005637 }
5638 if (thumbnail == null && !always) {
5639 // If there is no thumbnail, and this entry is not actually
5640 // going away, then abort for now and pick up the next
5641 // thumbnail we get.
5642 return;
5643 }
5644 task = r.task;
5645
5646 int N = mPendingThumbnails.size();
5647 int i=0;
5648 while (i<N) {
5649 PendingThumbnailsRecord pr =
5650 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5651 //System.out.println("Looking in " + pr.pendingRecords);
5652 if (pr.pendingRecords.remove(r)) {
5653 if (receivers == null) {
5654 receivers = new ArrayList();
5655 }
5656 receivers.add(pr);
5657 if (pr.pendingRecords.size() == 0) {
5658 pr.finished = true;
5659 mPendingThumbnails.remove(i);
5660 N--;
5661 continue;
5662 }
5663 }
5664 i++;
5665 }
5666 }
5667
5668 if (receivers != null) {
5669 final int N = receivers.size();
5670 for (int i=0; i<N; i++) {
5671 try {
5672 PendingThumbnailsRecord pr =
5673 (PendingThumbnailsRecord)receivers.get(i);
5674 pr.receiver.newThumbnail(
5675 task != null ? task.taskId : -1, thumbnail, description);
5676 if (pr.finished) {
5677 pr.receiver.finished();
5678 }
5679 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005680 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005681 }
5682 }
5683 }
5684 }
5685
5686 // =========================================================
5687 // CONTENT PROVIDERS
5688 // =========================================================
5689
Jeff Brown10e89712011-07-08 18:52:57 -07005690 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5691 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005692 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005693 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005694 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005695 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005696 } catch (RemoteException ex) {
5697 }
5698 if (providers != null) {
5699 final int N = providers.size();
5700 for (int i=0; i<N; i++) {
5701 ProviderInfo cpi =
5702 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005703 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5704 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005705 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005706 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005707 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005708 }
5709 app.pubProviders.put(cpi.name, cpr);
5710 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005711 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005712 }
5713 }
5714 return providers;
5715 }
5716
5717 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005718 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005719 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5720 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5721 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005722 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005723 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005724 return null;
5725 }
5726 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005727 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005728 == PackageManager.PERMISSION_GRANTED) {
5729 return null;
5730 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005731
5732 PathPermission[] pps = cpi.pathPermissions;
5733 if (pps != null) {
5734 int i = pps.length;
5735 while (i > 0) {
5736 i--;
5737 PathPermission pp = pps[i];
5738 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005739 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005740 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005741 return null;
5742 }
5743 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005744 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005745 == PackageManager.PERMISSION_GRANTED) {
5746 return null;
5747 }
5748 }
5749 }
5750
Dianne Hackbornb424b632010-08-18 15:59:05 -07005751 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5752 if (perms != null) {
5753 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5754 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5755 return null;
5756 }
5757 }
5758 }
5759
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005760 String msg;
5761 if (!cpi.exported) {
5762 msg = "Permission Denial: opening provider " + cpi.name
5763 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5764 + ", uid=" + callingUid + ") that is not exported from uid "
5765 + cpi.applicationInfo.uid;
5766 } else {
5767 msg = "Permission Denial: opening provider " + cpi.name
5768 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5769 + ", uid=" + callingUid + ") requires "
5770 + cpi.readPermission + " or " + cpi.writePermission;
5771 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005772 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005773 return msg;
5774 }
5775
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005776 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5777 if (r != null) {
5778 Integer cnt = r.conProviders.get(cpr);
5779 if (DEBUG_PROVIDER) Slog.v(TAG,
5780 "Adding provider requested by "
5781 + r.processName + " from process "
5782 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5783 + " cnt=" + (cnt == null ? 1 : cnt));
5784 if (cnt == null) {
5785 cpr.clients.add(r);
5786 r.conProviders.put(cpr, new Integer(1));
5787 return true;
5788 } else {
5789 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5790 }
5791 } else {
5792 cpr.externals++;
5793 }
5794 return false;
5795 }
5796
5797 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5798 if (r != null) {
5799 Integer cnt = r.conProviders.get(cpr);
5800 if (DEBUG_PROVIDER) Slog.v(TAG,
5801 "Removing provider requested by "
5802 + r.processName + " from process "
5803 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5804 + " cnt=" + cnt);
5805 if (cnt == null || cnt.intValue() <= 1) {
5806 cpr.clients.remove(r);
5807 r.conProviders.remove(cpr);
5808 return true;
5809 } else {
5810 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5811 }
5812 } else {
5813 cpr.externals++;
5814 }
5815 return false;
5816 }
5817
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005818 private final ContentProviderHolder getContentProviderImpl(
5819 IApplicationThread caller, String name) {
5820 ContentProviderRecord cpr;
5821 ProviderInfo cpi = null;
5822
5823 synchronized(this) {
5824 ProcessRecord r = null;
5825 if (caller != null) {
5826 r = getRecordForAppLocked(caller);
5827 if (r == null) {
5828 throw new SecurityException(
5829 "Unable to find app for caller " + caller
5830 + " (pid=" + Binder.getCallingPid()
5831 + ") when getting content provider " + name);
5832 }
5833 }
5834
5835 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005836 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005837 boolean providerRunning = cpr != null;
5838 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005840 String msg;
5841 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5842 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005843 }
5844
5845 if (r != null && cpr.canRunHere(r)) {
5846 // This provider has been published or is in the process
5847 // of being published... but it is also allowed to run
5848 // in the caller's process, so don't make a connection
5849 // and just let the caller instantiate its own instance.
5850 if (cpr.provider != null) {
5851 // don't give caller the provider object, it needs
5852 // to make its own.
5853 cpr = new ContentProviderRecord(cpr);
5854 }
5855 return cpr;
5856 }
5857
5858 final long origId = Binder.clearCallingIdentity();
5859
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005860 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005861 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005862 final boolean countChanged = incProviderCount(r, cpr);
5863 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005864 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005865 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005866 // make sure to count it as being accessed and thus
5867 // back up on the LRU list. This is good because
5868 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005869 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005870 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005871 }
5872
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005873 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005874 if (false) {
5875 if (cpr.name.flattenToShortString().equals(
5876 "com.android.providers.calendar/.CalendarProvider2")) {
5877 Slog.v(TAG, "****************** KILLING "
5878 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005879 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005880 }
5881 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005882 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005883 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5884 // NOTE: there is still a race here where a signal could be
5885 // pending on the process even though we managed to update its
5886 // adj level. Not sure what to do about this, but at least
5887 // the race is now smaller.
5888 if (!success) {
5889 // Uh oh... it looks like the provider's process
5890 // has been killed on us. We need to wait for a new
5891 // process to be started, and make sure its death
5892 // doesn't kill our process.
5893 Slog.i(TAG,
5894 "Existing provider " + cpr.name.flattenToShortString()
5895 + " is crashing; detaching " + r);
5896 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005897 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005898 if (!lastRef) {
5899 // This wasn't the last ref our process had on
5900 // the provider... we have now been killed, bail.
5901 return null;
5902 }
5903 providerRunning = false;
5904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005905 }
5906
5907 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005909
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005910 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005911 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005912 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005913 resolveContentProvider(name,
5914 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005915 } catch (RemoteException ex) {
5916 }
5917 if (cpi == null) {
5918 return null;
5919 }
5920
Dianne Hackbornb424b632010-08-18 15:59:05 -07005921 String msg;
5922 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5923 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005924 }
5925
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005926 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005927 && !cpi.processName.equals("system")) {
5928 // If this content provider does not run in the system
5929 // process, and the system is not yet ready to run other
5930 // processes, then fail fast instead of hanging.
5931 throw new IllegalArgumentException(
5932 "Attempt to launch content provider before system ready");
5933 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005934
5935 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5936 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005937 final boolean firstClass = cpr == null;
5938 if (firstClass) {
5939 try {
5940 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005941 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005942 getApplicationInfo(
5943 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005944 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005945 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005946 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005947 + cpi.name);
5948 return null;
5949 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005950 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005951 } catch (RemoteException ex) {
5952 // pm is in same process, this will never happen.
5953 }
5954 }
5955
5956 if (r != null && cpr.canRunHere(r)) {
5957 // If this is a multiprocess provider, then just return its
5958 // info and allow the caller to instantiate it. Only do
5959 // this if the provider is the same user as the caller's
5960 // process, or can run as root (so can be in any process).
5961 return cpr;
5962 }
5963
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005964 if (DEBUG_PROVIDER) {
5965 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005966 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005967 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005968 }
5969
5970 // This is single process, and our app is now connecting to it.
5971 // See if we are already in the process of launching this
5972 // provider.
5973 final int N = mLaunchingProviders.size();
5974 int i;
5975 for (i=0; i<N; i++) {
5976 if (mLaunchingProviders.get(i) == cpr) {
5977 break;
5978 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005979 }
5980
5981 // If the provider is not already being launched, then get it
5982 // started.
5983 if (i >= N) {
5984 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005985
5986 try {
5987 // Content provider is now in use, its package can't be stopped.
5988 try {
5989 AppGlobals.getPackageManager().setPackageStoppedState(
5990 cpr.appInfo.packageName, false);
5991 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005992 } catch (IllegalArgumentException e) {
5993 Slog.w(TAG, "Failed trying to unstop package "
5994 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005995 }
5996
5997 ProcessRecord proc = startProcessLocked(cpi.processName,
5998 cpr.appInfo, false, 0, "content provider",
5999 new ComponentName(cpi.applicationInfo.packageName,
6000 cpi.name), false);
6001 if (proc == null) {
6002 Slog.w(TAG, "Unable to launch app "
6003 + cpi.applicationInfo.packageName + "/"
6004 + cpi.applicationInfo.uid + " for provider "
6005 + name + ": process is bad");
6006 return null;
6007 }
6008 cpr.launchingApp = proc;
6009 mLaunchingProviders.add(cpr);
6010 } finally {
6011 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006013 }
6014
6015 // Make sure the provider is published (the same provider class
6016 // may be published under multiple names).
6017 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006018 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006019 }
6020 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006021 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006022 }
6023 }
6024
6025 // Wait for the provider to be published...
6026 synchronized (cpr) {
6027 while (cpr.provider == null) {
6028 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006029 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006030 + cpi.applicationInfo.packageName + "/"
6031 + cpi.applicationInfo.uid + " for provider "
6032 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006033 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006034 cpi.applicationInfo.packageName,
6035 cpi.applicationInfo.uid, name);
6036 return null;
6037 }
6038 try {
6039 cpr.wait();
6040 } catch (InterruptedException ex) {
6041 }
6042 }
6043 }
6044 return cpr;
6045 }
6046
6047 public final ContentProviderHolder getContentProvider(
6048 IApplicationThread caller, String name) {
6049 if (caller == null) {
6050 String msg = "null IApplicationThread when getting content provider "
6051 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006052 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006053 throw new SecurityException(msg);
6054 }
6055
6056 return getContentProviderImpl(caller, name);
6057 }
6058
6059 private ContentProviderHolder getContentProviderExternal(String name) {
6060 return getContentProviderImpl(null, name);
6061 }
6062
6063 /**
6064 * Drop a content provider from a ProcessRecord's bookkeeping
6065 * @param cpr
6066 */
6067 public void removeContentProvider(IApplicationThread caller, String name) {
6068 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006069 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006070 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006071 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006072 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006073 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006074 return;
6075 }
6076 final ProcessRecord r = getRecordForAppLocked(caller);
6077 if (r == null) {
6078 throw new SecurityException(
6079 "Unable to find app for caller " + caller +
6080 " when removing content provider " + name);
6081 }
6082 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006083 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6084 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006085 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006086 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08006087 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006088 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006089 return;
6090 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006091 if (decProviderCount(r, localCpr)) {
6092 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07006093 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006094 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006095 }
6096 }
6097
6098 private void removeContentProviderExternal(String name) {
6099 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006100 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006101 if(cpr == null) {
6102 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006103 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006104 return;
6105 }
6106
6107 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006108 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6109 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006110 localCpr.externals--;
6111 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006112 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 }
6114 updateOomAdjLocked();
6115 }
6116 }
6117
6118 public final void publishContentProviders(IApplicationThread caller,
6119 List<ContentProviderHolder> providers) {
6120 if (providers == null) {
6121 return;
6122 }
6123
6124 synchronized(this) {
6125 final ProcessRecord r = getRecordForAppLocked(caller);
6126 if (r == null) {
6127 throw new SecurityException(
6128 "Unable to find app for caller " + caller
6129 + " (pid=" + Binder.getCallingPid()
6130 + ") when publishing content providers");
6131 }
6132
6133 final long origId = Binder.clearCallingIdentity();
6134
6135 final int N = providers.size();
6136 for (int i=0; i<N; i++) {
6137 ContentProviderHolder src = providers.get(i);
6138 if (src == null || src.info == null || src.provider == null) {
6139 continue;
6140 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006141 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006142 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006143 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6144 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006145 String names[] = dst.info.authority.split(";");
6146 for (int j = 0; j < names.length; j++) {
6147 mProvidersByName.put(names[j], dst);
6148 }
6149
6150 int NL = mLaunchingProviders.size();
6151 int j;
6152 for (j=0; j<NL; j++) {
6153 if (mLaunchingProviders.get(j) == dst) {
6154 mLaunchingProviders.remove(j);
6155 j--;
6156 NL--;
6157 }
6158 }
6159 synchronized (dst) {
6160 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006161 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006162 dst.notifyAll();
6163 }
6164 updateOomAdjLocked(r);
6165 }
6166 }
6167
6168 Binder.restoreCallingIdentity(origId);
6169 }
6170 }
6171
6172 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006173 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006174 synchronized (mSelf) {
6175 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6176 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006177 if (providers != null) {
6178 for (int i=providers.size()-1; i>=0; i--) {
6179 ProviderInfo pi = (ProviderInfo)providers.get(i);
6180 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6181 Slog.w(TAG, "Not installing system proc provider " + pi.name
6182 + ": not system .apk");
6183 providers.remove(i);
6184 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006185 }
6186 }
6187 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006188 if (providers != null) {
6189 mSystemThread.installSystemProviders(providers);
6190 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006191
6192 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006193
6194 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006195 }
6196
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006197 /**
6198 * Allows app to retrieve the MIME type of a URI without having permission
6199 * to access its content provider.
6200 *
6201 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6202 *
6203 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6204 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6205 */
6206 public String getProviderMimeType(Uri uri) {
6207 final String name = uri.getAuthority();
6208 final long ident = Binder.clearCallingIdentity();
6209 ContentProviderHolder holder = null;
6210
6211 try {
6212 holder = getContentProviderExternal(name);
6213 if (holder != null) {
6214 return holder.provider.getType(uri);
6215 }
6216 } catch (RemoteException e) {
6217 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6218 return null;
6219 } finally {
6220 if (holder != null) {
6221 removeContentProviderExternal(name);
6222 }
6223 Binder.restoreCallingIdentity(ident);
6224 }
6225
6226 return null;
6227 }
6228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006229 // =========================================================
6230 // GLOBAL MANAGEMENT
6231 // =========================================================
6232
6233 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6234 ApplicationInfo info, String customProcess) {
6235 String proc = customProcess != null ? customProcess : info.processName;
6236 BatteryStatsImpl.Uid.Proc ps = null;
6237 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6238 synchronized (stats) {
6239 ps = stats.getProcessStatsLocked(info.uid, proc);
6240 }
6241 return new ProcessRecord(ps, thread, info, proc);
6242 }
6243
6244 final ProcessRecord addAppLocked(ApplicationInfo info) {
6245 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6246
6247 if (app == null) {
6248 app = newProcessRecordLocked(null, info, null);
6249 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006250 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006251 }
6252
Dianne Hackborne7f97212011-02-24 14:40:20 -08006253 // This package really, really can not be stopped.
6254 try {
6255 AppGlobals.getPackageManager().setPackageStoppedState(
6256 info.packageName, false);
6257 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006258 } catch (IllegalArgumentException e) {
6259 Slog.w(TAG, "Failed trying to unstop package "
6260 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006261 }
6262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006263 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6264 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6265 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006266 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006267 }
6268 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6269 mPersistentStartingProcesses.add(app);
6270 startProcessLocked(app, "added application", app.processName);
6271 }
6272
6273 return app;
6274 }
6275
6276 public void unhandledBack() {
6277 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6278 "unhandledBack()");
6279
6280 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006281 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006282 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006283 TAG, "Performing unhandledBack(): stack size = " + count);
6284 if (count > 1) {
6285 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006286 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006287 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6288 Binder.restoreCallingIdentity(origId);
6289 }
6290 }
6291 }
6292
6293 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6294 String name = uri.getAuthority();
6295 ContentProviderHolder cph = getContentProviderExternal(name);
6296 ParcelFileDescriptor pfd = null;
6297 if (cph != null) {
6298 // We record the binder invoker's uid in thread-local storage before
6299 // going to the content provider to open the file. Later, in the code
6300 // that handles all permissions checks, we look for this uid and use
6301 // that rather than the Activity Manager's own uid. The effect is that
6302 // we do the check against the caller's permissions even though it looks
6303 // to the content provider like the Activity Manager itself is making
6304 // the request.
6305 sCallerIdentity.set(new Identity(
6306 Binder.getCallingPid(), Binder.getCallingUid()));
6307 try {
6308 pfd = cph.provider.openFile(uri, "r");
6309 } catch (FileNotFoundException e) {
6310 // do nothing; pfd will be returned null
6311 } finally {
6312 // Ensure that whatever happens, we clean up the identity state
6313 sCallerIdentity.remove();
6314 }
6315
6316 // We've got the fd now, so we're done with the provider.
6317 removeContentProviderExternal(name);
6318 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006319 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006320 }
6321 return pfd;
6322 }
6323
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006324 // Actually is sleeping or shutting down or whatever else in the future
6325 // is an inactive state.
6326 public boolean isSleeping() {
6327 return mSleeping || mShuttingDown;
6328 }
6329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006330 public void goingToSleep() {
6331 synchronized(this) {
6332 mSleeping = true;
6333 mWindowManager.setEventDispatching(false);
6334
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006335 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006336
6337 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006338 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006339 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6340 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006341 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006342 }
6343 }
6344
Dianne Hackborn55280a92009-05-07 15:53:46 -07006345 public boolean shutdown(int timeout) {
6346 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6347 != PackageManager.PERMISSION_GRANTED) {
6348 throw new SecurityException("Requires permission "
6349 + android.Manifest.permission.SHUTDOWN);
6350 }
6351
6352 boolean timedout = false;
6353
6354 synchronized(this) {
6355 mShuttingDown = true;
6356 mWindowManager.setEventDispatching(false);
6357
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006358 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006359 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006360 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006361 while (mMainStack.mResumedActivity != null
6362 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006363 long delay = endTime - System.currentTimeMillis();
6364 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006365 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006366 timedout = true;
6367 break;
6368 }
6369 try {
6370 this.wait();
6371 } catch (InterruptedException e) {
6372 }
6373 }
6374 }
6375 }
6376
6377 mUsageStatsService.shutdown();
6378 mBatteryStatsService.shutdown();
6379
6380 return timedout;
6381 }
6382
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006383 public final void activitySlept(IBinder token) {
6384 if (localLOGV) Slog.v(
6385 TAG, "Activity slept: token=" + token);
6386
6387 ActivityRecord r = null;
6388
6389 final long origId = Binder.clearCallingIdentity();
6390
6391 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006392 r = mMainStack.isInStackLocked(token);
6393 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006394 mMainStack.activitySleptLocked(r);
6395 }
6396 }
6397
6398 Binder.restoreCallingIdentity(origId);
6399 }
6400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006401 public void wakingUp() {
6402 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006403 mWindowManager.setEventDispatching(true);
6404 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006405 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006406 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006407 }
6408 }
6409
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006410 public void stopAppSwitches() {
6411 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6412 != PackageManager.PERMISSION_GRANTED) {
6413 throw new SecurityException("Requires permission "
6414 + android.Manifest.permission.STOP_APP_SWITCHES);
6415 }
6416
6417 synchronized(this) {
6418 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6419 + APP_SWITCH_DELAY_TIME;
6420 mDidAppSwitch = false;
6421 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6422 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6423 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6424 }
6425 }
6426
6427 public void resumeAppSwitches() {
6428 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6429 != PackageManager.PERMISSION_GRANTED) {
6430 throw new SecurityException("Requires permission "
6431 + android.Manifest.permission.STOP_APP_SWITCHES);
6432 }
6433
6434 synchronized(this) {
6435 // Note that we don't execute any pending app switches... we will
6436 // let those wait until either the timeout, or the next start
6437 // activity request.
6438 mAppSwitchesAllowedTime = 0;
6439 }
6440 }
6441
6442 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6443 String name) {
6444 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6445 return true;
6446 }
6447
6448 final int perm = checkComponentPermission(
6449 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006450 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006451 if (perm == PackageManager.PERMISSION_GRANTED) {
6452 return true;
6453 }
6454
Joe Onorato8a9b2202010-02-26 18:56:32 -08006455 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006456 return false;
6457 }
6458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006459 public void setDebugApp(String packageName, boolean waitForDebugger,
6460 boolean persistent) {
6461 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6462 "setDebugApp()");
6463
6464 // Note that this is not really thread safe if there are multiple
6465 // callers into it at the same time, but that's not a situation we
6466 // care about.
6467 if (persistent) {
6468 final ContentResolver resolver = mContext.getContentResolver();
6469 Settings.System.putString(
6470 resolver, Settings.System.DEBUG_APP,
6471 packageName);
6472 Settings.System.putInt(
6473 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6474 waitForDebugger ? 1 : 0);
6475 }
6476
6477 synchronized (this) {
6478 if (!persistent) {
6479 mOrigDebugApp = mDebugApp;
6480 mOrigWaitForDebugger = mWaitForDebugger;
6481 }
6482 mDebugApp = packageName;
6483 mWaitForDebugger = waitForDebugger;
6484 mDebugTransient = !persistent;
6485 if (packageName != null) {
6486 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006487 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006488 Binder.restoreCallingIdentity(origId);
6489 }
6490 }
6491 }
6492
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006493 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6494 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6495 synchronized (this) {
6496 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6497 if (!isDebuggable) {
6498 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6499 throw new SecurityException("Process not debuggable: " + app.packageName);
6500 }
6501 }
6502 mProfileApp = processName;
6503 mProfileFile = profileFile;
6504 if (mProfileFd != null) {
6505 try {
6506 mProfileFd.close();
6507 } catch (IOException e) {
6508 }
6509 mProfileFd = null;
6510 }
6511 mProfileFd = profileFd;
6512 mProfileType = 0;
6513 mAutoStopProfiler = autoStopProfiler;
6514 }
6515 }
6516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006517 public void setAlwaysFinish(boolean enabled) {
6518 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6519 "setAlwaysFinish()");
6520
6521 Settings.System.putInt(
6522 mContext.getContentResolver(),
6523 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6524
6525 synchronized (this) {
6526 mAlwaysFinishActivities = enabled;
6527 }
6528 }
6529
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006530 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006531 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006532 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006533 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006534 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006535 }
6536 }
6537
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006538 public boolean isUserAMonkey() {
6539 // For now the fact that there is a controller implies
6540 // we have a monkey.
6541 synchronized (this) {
6542 return mController != null;
6543 }
6544 }
6545
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006546 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006547 synchronized (this) {
6548 mWatchers.register(watcher);
6549 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006550 }
6551
6552 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006553 synchronized (this) {
6554 mWatchers.unregister(watcher);
6555 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006556 }
6557
Jeff Sharkeya4620792011-05-20 15:29:23 -07006558 public void registerProcessObserver(IProcessObserver observer) {
6559 mProcessObservers.register(observer);
6560 }
6561
6562 public void unregisterProcessObserver(IProcessObserver observer) {
6563 mProcessObservers.unregister(observer);
6564 }
6565
Daniel Sandler69a48172010-06-23 16:29:36 -04006566 public void setImmersive(IBinder token, boolean immersive) {
6567 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006568 ActivityRecord r = mMainStack.isInStackLocked(token);
6569 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006570 throw new IllegalArgumentException();
6571 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006572 r.immersive = immersive;
6573 }
6574 }
6575
6576 public boolean isImmersive(IBinder token) {
6577 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006578 ActivityRecord r = mMainStack.isInStackLocked(token);
6579 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006580 throw new IllegalArgumentException();
6581 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006582 return r.immersive;
6583 }
6584 }
6585
6586 public boolean isTopActivityImmersive() {
6587 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006588 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006589 return (r != null) ? r.immersive : false;
6590 }
6591 }
6592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006593 public final void enterSafeMode() {
6594 synchronized(this) {
6595 // It only makes sense to do this before the system is ready
6596 // and started launching other packages.
6597 if (!mSystemReady) {
6598 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006599 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006600 } catch (RemoteException e) {
6601 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006602 }
6603 }
6604 }
6605
Jeff Brownb09abc12011-01-13 21:08:27 -08006606 public final void showSafeModeOverlay() {
6607 View v = LayoutInflater.from(mContext).inflate(
6608 com.android.internal.R.layout.safe_mode, null);
6609 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6610 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6611 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6612 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6613 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6614 lp.format = v.getBackground().getOpacity();
6615 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6616 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6617 ((WindowManager)mContext.getSystemService(
6618 Context.WINDOW_SERVICE)).addView(v, lp);
6619 }
6620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006621 public void noteWakeupAlarm(IIntentSender sender) {
6622 if (!(sender instanceof PendingIntentRecord)) {
6623 return;
6624 }
6625 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6626 synchronized (stats) {
6627 if (mBatteryStatsService.isOnBattery()) {
6628 mBatteryStatsService.enforceCallingPermission();
6629 PendingIntentRecord rec = (PendingIntentRecord)sender;
6630 int MY_UID = Binder.getCallingUid();
6631 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6632 BatteryStatsImpl.Uid.Pkg pkg =
6633 stats.getPackageStatsLocked(uid, rec.key.packageName);
6634 pkg.incWakeupsLocked();
6635 }
6636 }
6637 }
6638
Dianne Hackborn64825172011-03-02 21:32:58 -08006639 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006640 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006641 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006642 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006643 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006644 // XXX Note: don't acquire main activity lock here, because the window
6645 // manager calls in with its locks held.
6646
6647 boolean killed = false;
6648 synchronized (mPidsSelfLocked) {
6649 int[] types = new int[pids.length];
6650 int worstType = 0;
6651 for (int i=0; i<pids.length; i++) {
6652 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6653 if (proc != null) {
6654 int type = proc.setAdj;
6655 types[i] = type;
6656 if (type > worstType) {
6657 worstType = type;
6658 }
6659 }
6660 }
6661
Dianne Hackborn64825172011-03-02 21:32:58 -08006662 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006664 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
6665 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07006666 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006667 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006668
6669 // If this is not a secure call, don't let it kill processes that
6670 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006671 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
6672 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006673 }
6674
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006675 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006676 for (int i=0; i<pids.length; i++) {
6677 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6678 if (proc == null) {
6679 continue;
6680 }
6681 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006682 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006683 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006684 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6685 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006686 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006687 proc.killedBackground = true;
6688 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006689 }
6690 }
6691 }
6692 return killed;
6693 }
6694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006695 public final void startRunning(String pkg, String cls, String action,
6696 String data) {
6697 synchronized(this) {
6698 if (mStartRunning) {
6699 return;
6700 }
6701 mStartRunning = true;
6702 mTopComponent = pkg != null && cls != null
6703 ? new ComponentName(pkg, cls) : null;
6704 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6705 mTopData = data;
6706 if (!mSystemReady) {
6707 return;
6708 }
6709 }
6710
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006711 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006712 }
6713
6714 private void retrieveSettings() {
6715 final ContentResolver resolver = mContext.getContentResolver();
6716 String debugApp = Settings.System.getString(
6717 resolver, Settings.System.DEBUG_APP);
6718 boolean waitForDebugger = Settings.System.getInt(
6719 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6720 boolean alwaysFinishActivities = Settings.System.getInt(
6721 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6722
6723 Configuration configuration = new Configuration();
6724 Settings.System.getConfiguration(resolver, configuration);
6725
6726 synchronized (this) {
6727 mDebugApp = mOrigDebugApp = debugApp;
6728 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6729 mAlwaysFinishActivities = alwaysFinishActivities;
6730 // This happens before any activities are started, so we can
6731 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08006732 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006733 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006734 }
6735 }
6736
6737 public boolean testIsSystemReady() {
6738 // no need to synchronize(this) just to read & return the value
6739 return mSystemReady;
6740 }
6741
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006742 private static File getCalledPreBootReceiversFile() {
6743 File dataDir = Environment.getDataDirectory();
6744 File systemDir = new File(dataDir, "system");
6745 File fname = new File(systemDir, "called_pre_boots.dat");
6746 return fname;
6747 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006748
6749 static final int LAST_DONE_VERSION = 10000;
6750
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006751 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6752 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6753 File file = getCalledPreBootReceiversFile();
6754 FileInputStream fis = null;
6755 try {
6756 fis = new FileInputStream(file);
6757 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006758 int fvers = dis.readInt();
6759 if (fvers == LAST_DONE_VERSION) {
6760 String vers = dis.readUTF();
6761 String codename = dis.readUTF();
6762 String build = dis.readUTF();
6763 if (android.os.Build.VERSION.RELEASE.equals(vers)
6764 && android.os.Build.VERSION.CODENAME.equals(codename)
6765 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6766 int num = dis.readInt();
6767 while (num > 0) {
6768 num--;
6769 String pkg = dis.readUTF();
6770 String cls = dis.readUTF();
6771 lastDoneReceivers.add(new ComponentName(pkg, cls));
6772 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006773 }
6774 }
6775 } catch (FileNotFoundException e) {
6776 } catch (IOException e) {
6777 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6778 } finally {
6779 if (fis != null) {
6780 try {
6781 fis.close();
6782 } catch (IOException e) {
6783 }
6784 }
6785 }
6786 return lastDoneReceivers;
6787 }
6788
6789 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6790 File file = getCalledPreBootReceiversFile();
6791 FileOutputStream fos = null;
6792 DataOutputStream dos = null;
6793 try {
6794 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6795 fos = new FileOutputStream(file);
6796 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006797 dos.writeInt(LAST_DONE_VERSION);
6798 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006799 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006800 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006801 dos.writeInt(list.size());
6802 for (int i=0; i<list.size(); i++) {
6803 dos.writeUTF(list.get(i).getPackageName());
6804 dos.writeUTF(list.get(i).getClassName());
6805 }
6806 } catch (IOException e) {
6807 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6808 file.delete();
6809 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006810 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006811 if (dos != null) {
6812 try {
6813 dos.close();
6814 } catch (IOException e) {
6815 // TODO Auto-generated catch block
6816 e.printStackTrace();
6817 }
6818 }
6819 }
6820 }
6821
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006822 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006823 synchronized(this) {
6824 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006825 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006826 return;
6827 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006828
6829 // Check to see if there are any update receivers to run.
6830 if (!mDidUpdate) {
6831 if (mWaitingUpdate) {
6832 return;
6833 }
6834 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6835 List<ResolveInfo> ris = null;
6836 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006837 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006838 intent, null, 0);
6839 } catch (RemoteException e) {
6840 }
6841 if (ris != null) {
6842 for (int i=ris.size()-1; i>=0; i--) {
6843 if ((ris.get(i).activityInfo.applicationInfo.flags
6844 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6845 ris.remove(i);
6846 }
6847 }
6848 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006849
6850 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6851
6852 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006853 for (int i=0; i<ris.size(); i++) {
6854 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006855 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6856 if (lastDoneReceivers.contains(comp)) {
6857 ris.remove(i);
6858 i--;
6859 }
6860 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006861
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006862 for (int i=0; i<ris.size(); i++) {
6863 ActivityInfo ai = ris.get(i).activityInfo;
6864 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6865 doneReceivers.add(comp);
6866 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006867 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006868 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006869 finisher = new IIntentReceiver.Stub() {
6870 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006871 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006872 boolean sticky) {
6873 // The raw IIntentReceiver interface is called
6874 // with the AM lock held, so redispatch to
6875 // execute our code without the lock.
6876 mHandler.post(new Runnable() {
6877 public void run() {
6878 synchronized (ActivityManagerService.this) {
6879 mDidUpdate = true;
6880 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006881 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006882 showBootMessage(mContext.getText(
6883 R.string.android_upgrading_complete),
6884 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006885 systemReady(goingCallback);
6886 }
6887 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006888 }
6889 };
6890 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006891 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006892 broadcastIntentLocked(null, null, intent, null, finisher,
6893 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006894 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006895 mWaitingUpdate = true;
6896 }
6897 }
6898 }
6899 if (mWaitingUpdate) {
6900 return;
6901 }
6902 mDidUpdate = true;
6903 }
6904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006905 mSystemReady = true;
6906 if (!mStartRunning) {
6907 return;
6908 }
6909 }
6910
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006911 ArrayList<ProcessRecord> procsToKill = null;
6912 synchronized(mPidsSelfLocked) {
6913 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6914 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6915 if (!isAllowedWhileBooting(proc.info)){
6916 if (procsToKill == null) {
6917 procsToKill = new ArrayList<ProcessRecord>();
6918 }
6919 procsToKill.add(proc);
6920 }
6921 }
6922 }
6923
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006924 synchronized(this) {
6925 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006926 for (int i=procsToKill.size()-1; i>=0; i--) {
6927 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006928 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08006929 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006930 }
6931 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006932
6933 // Now that we have cleaned up any update processes, we
6934 // are ready to start launching real processes and know that
6935 // we won't trample on them any more.
6936 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006937 }
6938
Joe Onorato8a9b2202010-02-26 18:56:32 -08006939 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006940 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006941 SystemClock.uptimeMillis());
6942
6943 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006944 // Make sure we have no pre-ready processes sitting around.
6945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006946 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6947 ResolveInfo ri = mContext.getPackageManager()
6948 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006949 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006950 CharSequence errorMsg = null;
6951 if (ri != null) {
6952 ActivityInfo ai = ri.activityInfo;
6953 ApplicationInfo app = ai.applicationInfo;
6954 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6955 mTopAction = Intent.ACTION_FACTORY_TEST;
6956 mTopData = null;
6957 mTopComponent = new ComponentName(app.packageName,
6958 ai.name);
6959 } else {
6960 errorMsg = mContext.getResources().getText(
6961 com.android.internal.R.string.factorytest_not_system);
6962 }
6963 } else {
6964 errorMsg = mContext.getResources().getText(
6965 com.android.internal.R.string.factorytest_no_action);
6966 }
6967 if (errorMsg != null) {
6968 mTopAction = null;
6969 mTopData = null;
6970 mTopComponent = null;
6971 Message msg = Message.obtain();
6972 msg.what = SHOW_FACTORY_ERROR_MSG;
6973 msg.getData().putCharSequence("msg", errorMsg);
6974 mHandler.sendMessage(msg);
6975 }
6976 }
6977 }
6978
6979 retrieveSettings();
6980
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006981 if (goingCallback != null) goingCallback.run();
6982
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006983 synchronized (this) {
6984 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6985 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006986 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006987 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006988 if (apps != null) {
6989 int N = apps.size();
6990 int i;
6991 for (i=0; i<N; i++) {
6992 ApplicationInfo info
6993 = (ApplicationInfo)apps.get(i);
6994 if (info != null &&
6995 !info.packageName.equals("android")) {
6996 addAppLocked(info);
6997 }
6998 }
6999 }
7000 } catch (RemoteException ex) {
7001 // pm is in same process, this will never happen.
7002 }
7003 }
7004
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007005 // Start up initial activity.
7006 mBooting = true;
7007
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007008 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007009 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007010 Message msg = Message.obtain();
7011 msg.what = SHOW_UID_ERROR_MSG;
7012 mHandler.sendMessage(msg);
7013 }
7014 } catch (RemoteException e) {
7015 }
7016
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007017 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007018 }
7019 }
7020
Dan Egnorb7f03672009-12-09 16:22:32 -08007021 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007022 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007023 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007024 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007025 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007026 startAppProblemLocked(app);
7027 app.stopFreezingAllLocked();
7028 return handleAppCrashLocked(app);
7029 }
7030
Dan Egnorb7f03672009-12-09 16:22:32 -08007031 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007032 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007033 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007034 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007035 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7036 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007037 startAppProblemLocked(app);
7038 app.stopFreezingAllLocked();
7039 }
7040
7041 /**
7042 * Generate a process error record, suitable for attachment to a ProcessRecord.
7043 *
7044 * @param app The ProcessRecord in which the error occurred.
7045 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7046 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007047 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007048 * @param shortMsg Short message describing the crash.
7049 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007050 * @param stackTrace Full crash stack trace, may be null.
7051 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007052 * @return Returns a fully-formed AppErrorStateInfo record.
7053 */
7054 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007055 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007056 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007058 report.condition = condition;
7059 report.processName = app.processName;
7060 report.pid = app.pid;
7061 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007062 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007063 report.shortMsg = shortMsg;
7064 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08007065 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007066
7067 return report;
7068 }
7069
Dan Egnor42471dd2010-01-07 17:25:22 -08007070 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007071 synchronized (this) {
7072 app.crashing = false;
7073 app.crashingReport = null;
7074 app.notResponding = false;
7075 app.notRespondingReport = null;
7076 if (app.anrDialog == fromDialog) {
7077 app.anrDialog = null;
7078 }
7079 if (app.waitDialog == fromDialog) {
7080 app.waitDialog = null;
7081 }
7082 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08007083 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007084 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07007085 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7086 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007087 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007088 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007089 }
7090 }
Dan Egnor42471dd2010-01-07 17:25:22 -08007091
Dan Egnorb7f03672009-12-09 16:22:32 -08007092 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007093 long now = SystemClock.uptimeMillis();
7094
7095 Long crashTime = mProcessCrashTimes.get(app.info.processName,
7096 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07007097 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007098 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08007099 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007100 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007101 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007102 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007103 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7104 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007105 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007106 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007107 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007108 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007109 }
7110 }
7111 if (!app.persistent) {
7112 // We don't want to start this process again until the user
7113 // explicitly does so... but for persistent process, we really
7114 // need to keep it running. If a persistent process is actually
7115 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08007116 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007117 app.info.processName);
7118 mBadProcesses.put(app.info.processName, app.info.uid, now);
7119 app.bad = true;
7120 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
7121 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07007122 // Don't let services in this process be restarted and potentially
7123 // annoy the user repeatedly. Unless it is persistent, since those
7124 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007125 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08007126 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007127 return false;
7128 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08007129 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007130 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007131 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007132 if (r.app == app) {
7133 // If the top running activity is from this crashing
7134 // process, then terminate it to avoid getting in a loop.
7135 Slog.w(TAG, " Force finishing activity "
7136 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08007137 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007138 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007139 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08007140 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007141 // stopped, to avoid a situation where one will get
7142 // re-start our crashing activity once it gets resumed again.
7143 index--;
7144 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007145 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007146 if (r.state == ActivityState.RESUMED
7147 || r.state == ActivityState.PAUSING
7148 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007149 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007150 Slog.w(TAG, " Force finishing activity "
7151 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007152 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007153 Activity.RESULT_CANCELED, null, "crashed");
7154 }
7155 }
7156 }
7157 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007158 }
7159
7160 // Bump up the crash count of any services currently running in the proc.
7161 if (app.services.size() != 0) {
7162 // Any services running in the application need to be placed
7163 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007164 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007165 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007166 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007167 sr.crashCount++;
7168 }
7169 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007170
7171 // If the crashing process is what we consider to be the "home process" and it has been
7172 // replaced by a third-party app, clear the package preferred activities from packages
7173 // with a home activity running in the process to prevent a repeatedly crashing app
7174 // from blocking the user to manually clear the list.
7175 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7176 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7177 Iterator it = mHomeProcess.activities.iterator();
7178 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007179 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007180 if (r.isHomeActivity) {
7181 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7182 try {
7183 ActivityThread.getPackageManager()
7184 .clearPackagePreferredActivities(r.packageName);
7185 } catch (RemoteException c) {
7186 // pm is in same process, this will never happen.
7187 }
7188 }
7189 }
7190 }
7191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007192 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7193 return true;
7194 }
7195
7196 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007197 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7198 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007199 skipCurrentReceiverLocked(app);
7200 }
7201
7202 void skipCurrentReceiverLocked(ProcessRecord app) {
7203 boolean reschedule = false;
7204 BroadcastRecord r = app.curReceiver;
7205 if (r != null) {
7206 // The current broadcast is waiting for this app's receiver
7207 // to be finished. Looks like that's not going to happen, so
7208 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007209 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007210 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7211 r.resultExtras, r.resultAbort, true);
7212 reschedule = true;
7213 }
7214 r = mPendingBroadcast;
7215 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007216 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007217 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007218 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007219 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7220 r.resultExtras, r.resultAbort, true);
7221 reschedule = true;
7222 }
7223 if (reschedule) {
7224 scheduleBroadcastsLocked();
7225 }
7226 }
7227
Dan Egnor60d87622009-12-16 16:32:58 -08007228 /**
7229 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7230 * The application process will exit immediately after this call returns.
7231 * @param app object of the crashing app, null for the system server
7232 * @param crashInfo describing the exception
7233 */
7234 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007235 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007236 final String processName = app == null ? "system_server"
7237 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007238
7239 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007240 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007241 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007242 crashInfo.exceptionClassName,
7243 crashInfo.exceptionMessage,
7244 crashInfo.throwFileName,
7245 crashInfo.throwLineNumber);
7246
Jeff Sharkeya353d262011-10-28 11:12:06 -07007247 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007248
7249 crashApplication(r, crashInfo);
7250 }
7251
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007252 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007253 IBinder app,
7254 int violationMask,
7255 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007256 ProcessRecord r = findAppProcess(app, "StrictMode");
7257 if (r == null) {
7258 return;
7259 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007260
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007261 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007262 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007263 boolean logIt = true;
7264 synchronized (mAlreadyLoggedViolatedStacks) {
7265 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7266 logIt = false;
7267 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007268 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007269 // the relative pain numbers, without logging all
7270 // the stack traces repeatedly. We'd want to do
7271 // likewise in the client code, which also does
7272 // dup suppression, before the Binder call.
7273 } else {
7274 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7275 mAlreadyLoggedViolatedStacks.clear();
7276 }
7277 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7278 }
7279 }
7280 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007281 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007282 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007283 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007284
7285 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7286 AppErrorResult result = new AppErrorResult();
7287 synchronized (this) {
7288 final long origId = Binder.clearCallingIdentity();
7289
7290 Message msg = Message.obtain();
7291 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7292 HashMap<String, Object> data = new HashMap<String, Object>();
7293 data.put("result", result);
7294 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007295 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007296 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007297 msg.obj = data;
7298 mHandler.sendMessage(msg);
7299
7300 Binder.restoreCallingIdentity(origId);
7301 }
7302 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007303 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007304 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007305 }
7306
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007307 // Depending on the policy in effect, there could be a bunch of
7308 // these in quick succession so we try to batch these together to
7309 // minimize disk writes, number of dropbox entries, and maximize
7310 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007311 private void logStrictModeViolationToDropBox(
7312 ProcessRecord process,
7313 StrictMode.ViolationInfo info) {
7314 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007315 return;
7316 }
7317 final boolean isSystemApp = process == null ||
7318 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7319 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007320 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007321 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7322 final DropBoxManager dbox = (DropBoxManager)
7323 mContext.getSystemService(Context.DROPBOX_SERVICE);
7324
7325 // Exit early if the dropbox isn't configured to accept this report type.
7326 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7327
7328 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007329 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007330 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7331 synchronized (sb) {
7332 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007333 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007334 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7335 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007336 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7337 if (info.violationNumThisLoop != 0) {
7338 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7339 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007340 if (info.numAnimationsRunning != 0) {
7341 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7342 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007343 if (info.broadcastIntentAction != null) {
7344 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7345 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007346 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007347 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007348 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007349 if (info.numInstances != -1) {
7350 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7351 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007352 if (info.tags != null) {
7353 for (String tag : info.tags) {
7354 sb.append("Span-Tag: ").append(tag).append("\n");
7355 }
7356 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007357 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007358 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7359 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007360 }
7361 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007362
7363 // Only buffer up to ~64k. Various logging bits truncate
7364 // things at 128k.
7365 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007366 }
7367
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007368 // Flush immediately if the buffer's grown too large, or this
7369 // is a non-system app. Non-system apps are isolated with a
7370 // different tag & policy and not batched.
7371 //
7372 // Batching is useful during internal testing with
7373 // StrictMode settings turned up high. Without batching,
7374 // thousands of separate files could be created on boot.
7375 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007376 new Thread("Error dump: " + dropboxTag) {
7377 @Override
7378 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007379 String report;
7380 synchronized (sb) {
7381 report = sb.toString();
7382 sb.delete(0, sb.length());
7383 sb.trimToSize();
7384 }
7385 if (report.length() != 0) {
7386 dbox.addText(dropboxTag, report);
7387 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007388 }
7389 }.start();
7390 return;
7391 }
7392
7393 // System app batching:
7394 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007395 // An existing dropbox-writing thread is outstanding, so
7396 // we don't need to start it up. The existing thread will
7397 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007398 return;
7399 }
7400
7401 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7402 // (After this point, we shouldn't access AMS internal data structures.)
7403 new Thread("Error dump: " + dropboxTag) {
7404 @Override
7405 public void run() {
7406 // 5 second sleep to let stacks arrive and be batched together
7407 try {
7408 Thread.sleep(5000); // 5 seconds
7409 } catch (InterruptedException e) {}
7410
7411 String errorReport;
7412 synchronized (mStrictModeBuffer) {
7413 errorReport = mStrictModeBuffer.toString();
7414 if (errorReport.length() == 0) {
7415 return;
7416 }
7417 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7418 mStrictModeBuffer.trimToSize();
7419 }
7420 dbox.addText(dropboxTag, errorReport);
7421 }
7422 }.start();
7423 }
7424
Dan Egnor60d87622009-12-16 16:32:58 -08007425 /**
7426 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7427 * @param app object of the crashing app, null for the system server
7428 * @param tag reported by the caller
7429 * @param crashInfo describing the context of the error
7430 * @return true if the process should exit immediately (WTF is fatal)
7431 */
7432 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007433 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007434 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007435 final String processName = app == null ? "system_server"
7436 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007437
7438 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007439 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007440 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007441 tag, crashInfo.exceptionMessage);
7442
Jeff Sharkeya353d262011-10-28 11:12:06 -07007443 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007444
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007445 if (r != null && r.pid != Process.myPid() &&
7446 Settings.Secure.getInt(mContext.getContentResolver(),
7447 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007448 crashApplication(r, crashInfo);
7449 return true;
7450 } else {
7451 return false;
7452 }
7453 }
7454
7455 /**
7456 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7457 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7458 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007459 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007460 if (app == null) {
7461 return null;
7462 }
7463
7464 synchronized (this) {
7465 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7466 final int NA = apps.size();
7467 for (int ia=0; ia<NA; ia++) {
7468 ProcessRecord p = apps.valueAt(ia);
7469 if (p.thread != null && p.thread.asBinder() == app) {
7470 return p;
7471 }
7472 }
7473 }
7474
Dianne Hackborncb44d962011-03-10 17:02:27 -08007475 Slog.w(TAG, "Can't find mystery application for " + reason
7476 + " from pid=" + Binder.getCallingPid()
7477 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007478 return null;
7479 }
7480 }
7481
7482 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007483 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7484 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007485 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07007486 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7487 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007488 // Watchdog thread ends up invoking this function (with
7489 // a null ProcessRecord) to add the stack file to dropbox.
7490 // Do not acquire a lock on this (am) in such cases, as it
7491 // could cause a potential deadlock, if and when watchdog
7492 // is invoked due to unavailability of lock on am and it
7493 // would prevent watchdog from killing system_server.
7494 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007495 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007496 return;
7497 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007498 // Note: ProcessRecord 'process' is guarded by the service
7499 // instance. (notably process.pkgList, which could otherwise change
7500 // concurrently during execution of this method)
7501 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007502 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08007503 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007504 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007505 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7506 for (String pkg : process.pkgList) {
7507 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007508 try {
Dan Egnora455d192010-03-12 08:52:28 -08007509 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7510 if (pi != null) {
7511 sb.append(" v").append(pi.versionCode);
7512 if (pi.versionName != null) {
7513 sb.append(" (").append(pi.versionName).append(")");
7514 }
7515 }
7516 } catch (RemoteException e) {
7517 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007518 }
Dan Egnora455d192010-03-12 08:52:28 -08007519 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007520 }
Dan Egnora455d192010-03-12 08:52:28 -08007521 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007522 }
7523
7524 private static String processClass(ProcessRecord process) {
7525 if (process == null || process.pid == MY_PID) {
7526 return "system_server";
7527 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7528 return "system_app";
7529 } else {
7530 return "data_app";
7531 }
7532 }
7533
7534 /**
7535 * Write a description of an error (crash, WTF, ANR) to the drop box.
7536 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7537 * @param process which caused the error, null means the system server
7538 * @param activity which triggered the error, null if unknown
7539 * @param parent activity related to the error, null if unknown
7540 * @param subject line related to the error, null if absent
7541 * @param report in long form describing the error, null if absent
7542 * @param logFile to include in the report, null if none
7543 * @param crashInfo giving an application stack trace, null if absent
7544 */
7545 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07007546 ProcessRecord process, String processName, ActivityRecord activity,
7547 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007548 final String report, final File logFile,
7549 final ApplicationErrorReport.CrashInfo crashInfo) {
7550 // NOTE -- this must never acquire the ActivityManagerService lock,
7551 // otherwise the watchdog may be prevented from resetting the system.
7552
7553 final String dropboxTag = processClass(process) + "_" + eventType;
7554 final DropBoxManager dbox = (DropBoxManager)
7555 mContext.getSystemService(Context.DROPBOX_SERVICE);
7556
7557 // Exit early if the dropbox isn't configured to accept this report type.
7558 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7559
7560 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07007561 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007562 if (activity != null) {
7563 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7564 }
7565 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7566 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7567 }
7568 if (parent != null && parent != activity) {
7569 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7570 }
7571 if (subject != null) {
7572 sb.append("Subject: ").append(subject).append("\n");
7573 }
7574 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007575 if (Debug.isDebuggerConnected()) {
7576 sb.append("Debugger: Connected\n");
7577 }
Dan Egnora455d192010-03-12 08:52:28 -08007578 sb.append("\n");
7579
7580 // Do the rest in a worker thread to avoid blocking the caller on I/O
7581 // (After this point, we shouldn't access AMS internal data structures.)
7582 Thread worker = new Thread("Error dump: " + dropboxTag) {
7583 @Override
7584 public void run() {
7585 if (report != null) {
7586 sb.append(report);
7587 }
7588 if (logFile != null) {
7589 try {
7590 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7591 } catch (IOException e) {
7592 Slog.e(TAG, "Error reading " + logFile, e);
7593 }
7594 }
7595 if (crashInfo != null && crashInfo.stackTrace != null) {
7596 sb.append(crashInfo.stackTrace);
7597 }
7598
7599 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7600 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7601 if (lines > 0) {
7602 sb.append("\n");
7603
7604 // Merge several logcat streams, and take the last N lines
7605 InputStreamReader input = null;
7606 try {
7607 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7608 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7609 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7610
7611 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7612 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7613 input = new InputStreamReader(logcat.getInputStream());
7614
7615 int num;
7616 char[] buf = new char[8192];
7617 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7618 } catch (IOException e) {
7619 Slog.e(TAG, "Error running logcat", e);
7620 } finally {
7621 if (input != null) try { input.close(); } catch (IOException e) {}
7622 }
7623 }
7624
7625 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007626 }
Dan Egnora455d192010-03-12 08:52:28 -08007627 };
7628
7629 if (process == null || process.pid == MY_PID) {
7630 worker.run(); // We may be about to die -- need to run this synchronously
7631 } else {
7632 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007633 }
7634 }
7635
7636 /**
7637 * Bring up the "unexpected error" dialog box for a crashing app.
7638 * Deal with edge cases (intercepts from instrumented applications,
7639 * ActivityController, error intent receivers, that sort of thing).
7640 * @param r the application crashing
7641 * @param crashInfo describing the failure
7642 */
7643 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007644 long timeMillis = System.currentTimeMillis();
7645 String shortMsg = crashInfo.exceptionClassName;
7646 String longMsg = crashInfo.exceptionMessage;
7647 String stackTrace = crashInfo.stackTrace;
7648 if (shortMsg != null && longMsg != null) {
7649 longMsg = shortMsg + ": " + longMsg;
7650 } else if (shortMsg != null) {
7651 longMsg = shortMsg;
7652 }
7653
Dan Egnor60d87622009-12-16 16:32:58 -08007654 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007655 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007656 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007657 try {
7658 String name = r != null ? r.processName : null;
7659 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007660 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007661 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007662 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007663 + " at watcher's request");
7664 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007665 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007666 }
7667 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007668 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007669 }
7670 }
7671
7672 final long origId = Binder.clearCallingIdentity();
7673
7674 // If this process is running instrumentation, finish it.
7675 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007676 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007677 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007678 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7679 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007680 Bundle info = new Bundle();
7681 info.putString("shortMsg", shortMsg);
7682 info.putString("longMsg", longMsg);
7683 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7684 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007685 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007686 }
7687
Dan Egnor60d87622009-12-16 16:32:58 -08007688 // If we can't identify the process or it's already exceeded its crash quota,
7689 // quit right away without showing a crash dialog.
7690 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007691 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007692 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007693 }
7694
7695 Message msg = Message.obtain();
7696 msg.what = SHOW_ERROR_MSG;
7697 HashMap data = new HashMap();
7698 data.put("result", result);
7699 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007700 msg.obj = data;
7701 mHandler.sendMessage(msg);
7702
7703 Binder.restoreCallingIdentity(origId);
7704 }
7705
7706 int res = result.get();
7707
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007708 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007709 synchronized (this) {
7710 if (r != null) {
7711 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7712 SystemClock.uptimeMillis());
7713 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007714 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007715 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007716 }
7717 }
7718
7719 if (appErrorIntent != null) {
7720 try {
7721 mContext.startActivity(appErrorIntent);
7722 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007723 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007724 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007725 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007726 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007727
7728 Intent createAppErrorIntentLocked(ProcessRecord r,
7729 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7730 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007731 if (report == null) {
7732 return null;
7733 }
7734 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7735 result.setComponent(r.errorReportReceiver);
7736 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7737 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7738 return result;
7739 }
7740
Dan Egnorb7f03672009-12-09 16:22:32 -08007741 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7742 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007743 if (r.errorReportReceiver == null) {
7744 return null;
7745 }
7746
7747 if (!r.crashing && !r.notResponding) {
7748 return null;
7749 }
7750
Dan Egnorb7f03672009-12-09 16:22:32 -08007751 ApplicationErrorReport report = new ApplicationErrorReport();
7752 report.packageName = r.info.packageName;
7753 report.installerPackageName = r.errorReportReceiver.getPackageName();
7754 report.processName = r.processName;
7755 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007756 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007757
Dan Egnorb7f03672009-12-09 16:22:32 -08007758 if (r.crashing) {
7759 report.type = ApplicationErrorReport.TYPE_CRASH;
7760 report.crashInfo = crashInfo;
7761 } else if (r.notResponding) {
7762 report.type = ApplicationErrorReport.TYPE_ANR;
7763 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007764
Dan Egnorb7f03672009-12-09 16:22:32 -08007765 report.anrInfo.activity = r.notRespondingReport.tag;
7766 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7767 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007768 }
7769
Dan Egnorb7f03672009-12-09 16:22:32 -08007770 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007771 }
7772
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007773 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7774 // assume our apps are happy - lazy create the list
7775 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7776
7777 synchronized (this) {
7778
7779 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007780 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7781 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007782 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7783 // This one's in trouble, so we'll generate a report for it
7784 // crashes are higher priority (in case there's a crash *and* an anr)
7785 ActivityManager.ProcessErrorStateInfo report = null;
7786 if (app.crashing) {
7787 report = app.crashingReport;
7788 } else if (app.notResponding) {
7789 report = app.notRespondingReport;
7790 }
7791
7792 if (report != null) {
7793 if (errList == null) {
7794 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7795 }
7796 errList.add(report);
7797 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007798 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007799 " crashing = " + app.crashing +
7800 " notResponding = " + app.notResponding);
7801 }
7802 }
7803 }
7804 }
7805
7806 return errList;
7807 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007808
7809 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007810 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007811 if (currApp != null) {
7812 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7813 }
7814 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007815 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
7816 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007817 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7818 if (currApp != null) {
7819 currApp.lru = 0;
7820 }
7821 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007822 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007823 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7824 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7825 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7826 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7827 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7828 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7829 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7830 } else {
7831 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7832 }
7833 }
7834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007835 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7836 // Lazy instantiation of list
7837 List<ActivityManager.RunningAppProcessInfo> runList = null;
7838 synchronized (this) {
7839 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007840 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7841 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007842 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7843 // Generate process state info for running application
7844 ActivityManager.RunningAppProcessInfo currApp =
7845 new ActivityManager.RunningAppProcessInfo(app.processName,
7846 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007847 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007848 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007849 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007850 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007851 if (app.persistent) {
7852 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7853 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007854 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007855 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007856 currApp.importanceReasonCode = app.adjTypeCode;
7857 if (app.adjSource instanceof ProcessRecord) {
7858 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007859 currApp.importanceReasonImportance = oomAdjToImportance(
7860 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007861 } else if (app.adjSource instanceof ActivityRecord) {
7862 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007863 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7864 }
7865 if (app.adjTarget instanceof ComponentName) {
7866 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7867 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007868 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007869 // + " lru=" + currApp.lru);
7870 if (runList == null) {
7871 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7872 }
7873 runList.add(currApp);
7874 }
7875 }
7876 }
7877 return runList;
7878 }
7879
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007880 public List<ApplicationInfo> getRunningExternalApplications() {
7881 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7882 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7883 if (runningApps != null && runningApps.size() > 0) {
7884 Set<String> extList = new HashSet<String>();
7885 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7886 if (app.pkgList != null) {
7887 for (String pkg : app.pkgList) {
7888 extList.add(pkg);
7889 }
7890 }
7891 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007892 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007893 for (String pkg : extList) {
7894 try {
7895 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7896 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7897 retList.add(info);
7898 }
7899 } catch (RemoteException e) {
7900 }
7901 }
7902 }
7903 return retList;
7904 }
7905
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007906 @Override
7907 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007908 if (checkCallingPermission(android.Manifest.permission.DUMP)
7909 != PackageManager.PERMISSION_GRANTED) {
7910 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7911 + Binder.getCallingPid()
7912 + ", uid=" + Binder.getCallingUid()
7913 + " without permission "
7914 + android.Manifest.permission.DUMP);
7915 return;
7916 }
7917
7918 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007919 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007920 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007921
7922 int opti = 0;
7923 while (opti < args.length) {
7924 String opt = args[opti];
7925 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7926 break;
7927 }
7928 opti++;
7929 if ("-a".equals(opt)) {
7930 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007931 } else if ("-c".equals(opt)) {
7932 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007933 } else if ("-h".equals(opt)) {
7934 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007935 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007936 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007937 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007938 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
7939 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
7940 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007941 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007942 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7943 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007944 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007945 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007946 pw.println(" all: dump all activities");
7947 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007948 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007949 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7950 pw.println(" a partial substring in a component name, a");
7951 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007952 pw.println(" -a: include all available server state.");
7953 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007954 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007955 } else {
7956 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007957 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007958 }
7959
7960 // Is the caller requesting to dump a particular piece of data?
7961 if (opti < args.length) {
7962 String cmd = args[opti];
7963 opti++;
7964 if ("activities".equals(cmd) || "a".equals(cmd)) {
7965 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007966 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007967 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007968 return;
7969 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007970 String[] newArgs;
7971 String name;
7972 if (opti >= args.length) {
7973 name = null;
7974 newArgs = EMPTY_STRING_ARRAY;
7975 } else {
7976 name = args[opti];
7977 opti++;
7978 newArgs = new String[args.length - opti];
7979 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
7980 args.length - opti);
7981 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007982 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007983 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007984 }
7985 return;
7986 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007987 String[] newArgs;
7988 String name;
7989 if (opti >= args.length) {
7990 name = null;
7991 newArgs = EMPTY_STRING_ARRAY;
7992 } else {
7993 name = args[opti];
7994 opti++;
7995 newArgs = new String[args.length - opti];
7996 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
7997 args.length - opti);
7998 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007999 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008000 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008001 }
8002 return;
8003 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008004 String[] newArgs;
8005 String name;
8006 if (opti >= args.length) {
8007 name = null;
8008 newArgs = EMPTY_STRING_ARRAY;
8009 } else {
8010 name = args[opti];
8011 opti++;
8012 newArgs = new String[args.length - opti];
8013 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8014 args.length - opti);
8015 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008016 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008017 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008018 }
8019 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008020 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8021 synchronized (this) {
8022 dumpOomLocked(fd, pw, args, opti, true);
8023 }
8024 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008025 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8026 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008027 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008028 }
8029 return;
8030 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008031 String[] newArgs;
8032 String name;
8033 if (opti >= args.length) {
8034 name = null;
8035 newArgs = EMPTY_STRING_ARRAY;
8036 } else {
8037 name = args[opti];
8038 opti++;
8039 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008040 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8041 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008042 }
8043 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8044 pw.println("No services match: " + name);
8045 pw.println("Use -h for help.");
8046 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008047 return;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008048 } else if ("package".equals(cmd)) {
8049 String[] newArgs;
8050 if (opti >= args.length) {
8051 pw.println("package: no package name specified");
8052 pw.println("Use -h for help.");
8053 return;
8054 } else {
8055 dumpPackage = args[opti];
8056 opti++;
8057 newArgs = new String[args.length - opti];
8058 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8059 args.length - opti);
8060 args = newArgs;
8061 opti = 0;
8062 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008063 } else if ("services".equals(cmd) || "s".equals(cmd)) {
8064 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008065 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008066 }
8067 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07008068 } else {
8069 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008070 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8071 pw.println("Bad activity command, or no activities match: " + cmd);
8072 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008073 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008074 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008075 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008076 }
8077
8078 // No piece of data specified, dump everything.
8079 synchronized (this) {
8080 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008081 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008082 if (needSep) {
8083 pw.println(" ");
8084 }
8085 if (dumpAll) {
8086 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008087 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008088 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008089 if (needSep) {
8090 pw.println(" ");
8091 }
8092 if (dumpAll) {
8093 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008094 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008095 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008096 if (needSep) {
8097 pw.println(" ");
8098 }
8099 if (dumpAll) {
8100 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008101 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008102 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008103 if (needSep) {
8104 pw.println(" ");
8105 }
8106 if (dumpAll) {
8107 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008108 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008109 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008110 if (needSep) {
8111 pw.println(" ");
8112 }
8113 if (dumpAll) {
8114 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008115 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008116 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008117 }
8118 }
8119
8120 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008121 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008122 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8123 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008124 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
8125 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008126 pw.println(" ");
8127 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008128 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
8129 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008130 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008131 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008132 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008133 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008134 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008135 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008136 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008137 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008138 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008139 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008140 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008141 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008142 if (mMainStack.mGoingToSleepActivities.size() > 0) {
8143 pw.println(" ");
8144 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008145 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008146 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008147 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008148 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008149 pw.println(" ");
8150 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008151 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008152 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008154
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008155 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008156 if (mMainStack.mPausingActivity != null) {
8157 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
8158 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008159 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008160 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008161 if (dumpAll) {
8162 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8163 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008164 pw.println(" mDismissKeyguardOnNextActivity: "
8165 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008166 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008167
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008168 if (mRecentTasks.size() > 0) {
8169 pw.println();
8170 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008171
8172 final int N = mRecentTasks.size();
8173 for (int i=0; i<N; i++) {
8174 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008175 if (dumpPackage != null) {
8176 if (tr.realActivity == null ||
8177 !dumpPackage.equals(tr.realActivity)) {
8178 continue;
8179 }
8180 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008181 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
8182 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008183 if (dumpAll) {
8184 mRecentTasks.get(i).dump(pw, " ");
8185 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008186 }
8187 }
8188
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008189 if (dumpAll) {
8190 pw.println(" ");
8191 pw.println(" mCurTask: " + mCurTask);
8192 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008193
8194 return true;
8195 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008196
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008197 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008198 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008199 boolean needSep = false;
8200 int numPers = 0;
8201
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008202 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8203
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008204 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008205 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8206 final int NA = procs.size();
8207 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008208 ProcessRecord r = procs.valueAt(ia);
8209 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8210 continue;
8211 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008212 if (!needSep) {
8213 pw.println(" All known processes:");
8214 needSep = true;
8215 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008216 pw.print(r.persistent ? " *PERS*" : " *APP*");
8217 pw.print(" UID "); pw.print(procs.keyAt(ia));
8218 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008219 r.dump(pw, " ");
8220 if (r.persistent) {
8221 numPers++;
8222 }
8223 }
8224 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008225 }
8226
8227 if (mLruProcesses.size() > 0) {
8228 if (needSep) pw.println(" ");
8229 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008230 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008231 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008232 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008233 needSep = true;
8234 }
8235
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008236 if (dumpAll) {
8237 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008238 boolean printed = false;
8239 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8240 ProcessRecord r = mPidsSelfLocked.valueAt(i);
8241 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8242 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008243 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008244 if (!printed) {
8245 if (needSep) pw.println(" ");
8246 needSep = true;
8247 pw.println(" PID mappings:");
8248 printed = true;
8249 }
8250 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8251 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008252 }
8253 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008254 }
8255
8256 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008257 synchronized (mPidsSelfLocked) {
8258 boolean printed = false;
8259 for (int i=0; i<mForegroundProcesses.size(); i++) {
8260 ProcessRecord r = mPidsSelfLocked.get(
8261 mForegroundProcesses.valueAt(i).pid);
8262 if (dumpPackage != null && (r == null
8263 || !dumpPackage.equals(r.info.packageName))) {
8264 continue;
8265 }
8266 if (!printed) {
8267 if (needSep) pw.println(" ");
8268 needSep = true;
8269 pw.println(" Foreground Processes:");
8270 printed = true;
8271 }
8272 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8273 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8274 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008275 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008276 }
8277
8278 if (mPersistentStartingProcesses.size() > 0) {
8279 if (needSep) pw.println(" ");
8280 needSep = true;
8281 pw.println(" Persisent processes that are starting:");
8282 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008283 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008285
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008286 if (mRemovedProcesses.size() > 0) {
8287 if (needSep) pw.println(" ");
8288 needSep = true;
8289 pw.println(" Processes that are being removed:");
8290 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008291 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008292 }
8293
8294 if (mProcessesOnHold.size() > 0) {
8295 if (needSep) pw.println(" ");
8296 needSep = true;
8297 pw.println(" Processes that are on old until the system is ready:");
8298 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008299 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008301
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008302 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008303
8304 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008305 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008306 long now = SystemClock.uptimeMillis();
8307 for (Map.Entry<String, SparseArray<Long>> procs
8308 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008309 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008310 SparseArray<Long> uids = procs.getValue();
8311 final int N = uids.size();
8312 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008313 int puid = uids.keyAt(i);
8314 ProcessRecord r = mProcessNames.get(pname, puid);
8315 if (dumpPackage != null && (r == null
8316 || !dumpPackage.equals(r.info.packageName))) {
8317 continue;
8318 }
8319 if (!printed) {
8320 if (needSep) pw.println(" ");
8321 needSep = true;
8322 pw.println(" Time since processes crashed:");
8323 printed = true;
8324 }
8325 pw.print(" Process "); pw.print(pname);
8326 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008327 pw.print(": last crashed ");
8328 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008329 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008330 }
8331 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008332 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008333
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008334 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008335 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008336 for (Map.Entry<String, SparseArray<Long>> procs
8337 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008338 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008339 SparseArray<Long> uids = procs.getValue();
8340 final int N = uids.size();
8341 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008342 int puid = uids.keyAt(i);
8343 ProcessRecord r = mProcessNames.get(pname, puid);
8344 if (dumpPackage != null && (r == null
8345 || !dumpPackage.equals(r.info.packageName))) {
8346 continue;
8347 }
8348 if (!printed) {
8349 if (needSep) pw.println(" ");
8350 needSep = true;
8351 pw.println(" Bad processes:");
8352 }
8353 pw.print(" Bad process "); pw.print(pname);
8354 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008355 pw.print(": crashed at time ");
8356 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008357 }
8358 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008360
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008361 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008362 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008363 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008364 if (mHeavyWeightProcess != null) {
8365 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8366 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008367 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008368 if (dumpAll) {
8369 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008370 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008371 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008372 for (Map.Entry<String, Integer> entry
8373 : mCompatModePackages.getPackages().entrySet()) {
8374 String pkg = entry.getKey();
8375 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008376 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
8377 continue;
8378 }
8379 if (!printed) {
8380 pw.println(" mScreenCompatPackages:");
8381 printed = true;
8382 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008383 pw.print(" "); pw.print(pkg); pw.print(": ");
8384 pw.print(mode); pw.println();
8385 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008386 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008387 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008388 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8389 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8390 || mOrigWaitForDebugger) {
8391 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8392 + " mDebugTransient=" + mDebugTransient
8393 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8394 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008395 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8396 || mProfileFd != null) {
8397 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8398 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8399 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8400 + mAutoStopProfiler);
8401 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008402 if (mAlwaysFinishActivities || mController != null) {
8403 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8404 + " mController=" + mController);
8405 }
8406 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008407 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008408 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008409 + " mProcessesReady=" + mProcessesReady
8410 + " mSystemReady=" + mSystemReady);
8411 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008412 + " mBooted=" + mBooted
8413 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008414 pw.print(" mLastPowerCheckRealtime=");
8415 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8416 pw.println("");
8417 pw.print(" mLastPowerCheckUptime=");
8418 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8419 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008420 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8421 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008422 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008423 pw.println(" mNumServiceProcs=" + mNumServiceProcs
8424 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008425 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008426
8427 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008428 }
8429
Dianne Hackborn287952c2010-09-22 22:34:31 -07008430 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008431 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008432 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008433 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008434 long now = SystemClock.uptimeMillis();
8435 for (int i=0; i<mProcessesToGc.size(); i++) {
8436 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008437 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
8438 continue;
8439 }
8440 if (!printed) {
8441 if (needSep) pw.println(" ");
8442 needSep = true;
8443 pw.println(" Processes that are waiting to GC:");
8444 printed = true;
8445 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008446 pw.print(" Process "); pw.println(proc);
8447 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8448 pw.print(", last gced=");
8449 pw.print(now-proc.lastRequestedGc);
8450 pw.print(" ms ago, last lowMem=");
8451 pw.print(now-proc.lastLowMemory);
8452 pw.println(" ms ago");
8453
8454 }
8455 }
8456 return needSep;
8457 }
8458
8459 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8460 int opti, boolean dumpAll) {
8461 boolean needSep = false;
8462
8463 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008464 if (needSep) pw.println(" ");
8465 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008466 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008467 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008468 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008469 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8470 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8471 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8472 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8473 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008474 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008475 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008476 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008477 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008478 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008479 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008480
8481 if (needSep) pw.println(" ");
8482 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008483 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008484 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008485 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008486 needSep = true;
8487 }
8488
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008489 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008490
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008491 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008492 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008493 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008494 if (mHeavyWeightProcess != null) {
8495 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8496 }
8497
8498 return true;
8499 }
8500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008501 /**
8502 * There are three ways to call this:
8503 * - no service specified: dump all the services
8504 * - a flattened component name that matched an existing service was specified as the
8505 * first arg: dump that one service
8506 * - the first arg isn't the flattened component name of an existing service:
8507 * dump all services whose component contains the first arg as a substring
8508 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008509 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8510 int opti, boolean dumpAll) {
8511 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008512
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008513 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008514 synchronized (this) {
8515 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008516 services.add(r1);
8517 }
8518 }
8519 } else {
8520 ComponentName componentName = name != null
8521 ? ComponentName.unflattenFromString(name) : null;
8522 int objectId = 0;
8523 if (componentName == null) {
8524 // Not a '/' separated full component name; maybe an object ID?
8525 try {
8526 objectId = Integer.parseInt(name, 16);
8527 name = null;
8528 componentName = null;
8529 } catch (RuntimeException e) {
8530 }
8531 }
8532
8533 synchronized (this) {
8534 for (ServiceRecord r1 : mServices.values()) {
8535 if (componentName != null) {
8536 if (r1.name.equals(componentName)) {
8537 services.add(r1);
8538 }
8539 } else if (name != null) {
8540 if (r1.name.flattenToString().contains(name)) {
8541 services.add(r1);
8542 }
8543 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008544 services.add(r1);
8545 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008546 }
8547 }
8548 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008549
8550 if (services.size() <= 0) {
8551 return false;
8552 }
8553
8554 boolean needSep = false;
8555 for (int i=0; i<services.size(); i++) {
8556 if (needSep) {
8557 pw.println();
8558 }
8559 needSep = true;
8560 dumpService("", fd, pw, services.get(i), args, dumpAll);
8561 }
8562 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008563 }
8564
8565 /**
8566 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8567 * there is a thread associated with the service.
8568 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008569 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8570 final ServiceRecord r, String[] args, boolean dumpAll) {
8571 String innerPrefix = prefix + " ";
8572 synchronized (this) {
8573 pw.print(prefix); pw.print("SERVICE ");
8574 pw.print(r.shortName); pw.print(" ");
8575 pw.print(Integer.toHexString(System.identityHashCode(r)));
8576 pw.print(" pid=");
8577 if (r.app != null) pw.println(r.app.pid);
8578 else pw.println("(not running)");
8579 if (dumpAll) {
8580 r.dump(pw, innerPrefix);
8581 }
8582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008583 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008584 pw.print(prefix); pw.println(" Client:");
8585 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008586 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008587 TransferPipe tp = new TransferPipe();
8588 try {
8589 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8590 tp.setBufferPrefix(prefix + " ");
8591 tp.go(fd);
8592 } finally {
8593 tp.kill();
8594 }
8595 } catch (IOException e) {
8596 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008597 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008598 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008599 }
8600 }
8601 }
8602
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008603 static class ItemMatcher {
8604 ArrayList<ComponentName> components;
8605 ArrayList<String> strings;
8606 ArrayList<Integer> objects;
8607 boolean all;
8608
8609 ItemMatcher() {
8610 all = true;
8611 }
8612
8613 void build(String name) {
8614 ComponentName componentName = ComponentName.unflattenFromString(name);
8615 if (componentName != null) {
8616 if (components == null) {
8617 components = new ArrayList<ComponentName>();
8618 }
8619 components.add(componentName);
8620 all = false;
8621 } else {
8622 int objectId = 0;
8623 // Not a '/' separated full component name; maybe an object ID?
8624 try {
8625 objectId = Integer.parseInt(name, 16);
8626 if (objects == null) {
8627 objects = new ArrayList<Integer>();
8628 }
8629 objects.add(objectId);
8630 all = false;
8631 } catch (RuntimeException e) {
8632 // Not an integer; just do string match.
8633 if (strings == null) {
8634 strings = new ArrayList<String>();
8635 }
8636 strings.add(name);
8637 all = false;
8638 }
8639 }
8640 }
8641
8642 int build(String[] args, int opti) {
8643 for (; opti<args.length; opti++) {
8644 String name = args[opti];
8645 if ("--".equals(name)) {
8646 return opti+1;
8647 }
8648 build(name);
8649 }
8650 return opti;
8651 }
8652
8653 boolean match(Object object, ComponentName comp) {
8654 if (all) {
8655 return true;
8656 }
8657 if (components != null) {
8658 for (int i=0; i<components.size(); i++) {
8659 if (components.get(i).equals(comp)) {
8660 return true;
8661 }
8662 }
8663 }
8664 if (objects != null) {
8665 for (int i=0; i<objects.size(); i++) {
8666 if (System.identityHashCode(object) == objects.get(i)) {
8667 return true;
8668 }
8669 }
8670 }
8671 if (strings != null) {
8672 String flat = comp.flattenToString();
8673 for (int i=0; i<strings.size(); i++) {
8674 if (flat.contains(strings.get(i))) {
8675 return true;
8676 }
8677 }
8678 }
8679 return false;
8680 }
8681 }
8682
Dianne Hackborn625ac272010-09-17 18:29:22 -07008683 /**
8684 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008685 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008686 * - the cmd arg isn't the flattened component name of an existing activity:
8687 * dump all activity whose component contains the cmd as a substring
8688 * - A hex number of the ActivityRecord object instance.
8689 */
8690 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8691 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008692 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008693
8694 if ("all".equals(name)) {
8695 synchronized (this) {
8696 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008697 activities.add(r1);
8698 }
8699 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008700 } else if ("top".equals(name)) {
8701 synchronized (this) {
8702 final int N = mMainStack.mHistory.size();
8703 if (N > 0) {
8704 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8705 }
8706 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008707 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008708 ItemMatcher matcher = new ItemMatcher();
8709 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008710
8711 synchronized (this) {
8712 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008713 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008714 activities.add(r1);
8715 }
8716 }
8717 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008718 }
8719
8720 if (activities.size() <= 0) {
8721 return false;
8722 }
8723
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008724 String[] newArgs = new String[args.length - opti];
8725 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8726
Dianne Hackborn30d71892010-12-11 10:37:55 -08008727 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008728 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008729 for (int i=activities.size()-1; i>=0; i--) {
8730 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008731 if (needSep) {
8732 pw.println();
8733 }
8734 needSep = true;
8735 synchronized (this) {
8736 if (lastTask != r.task) {
8737 lastTask = r.task;
8738 pw.print("TASK "); pw.print(lastTask.affinity);
8739 pw.print(" id="); pw.println(lastTask.taskId);
8740 if (dumpAll) {
8741 lastTask.dump(pw, " ");
8742 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008743 }
8744 }
8745 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008746 }
8747 return true;
8748 }
8749
8750 /**
8751 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8752 * there is a thread associated with the activity.
8753 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008754 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008755 final ActivityRecord r, String[] args, boolean dumpAll) {
8756 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008757 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008758 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8759 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8760 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008761 if (r.app != null) pw.println(r.app.pid);
8762 else pw.println("(not running)");
8763 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008764 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008765 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008766 }
8767 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008768 // flush anything that is already in the PrintWriter since the thread is going
8769 // to write to the file descriptor directly
8770 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008771 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008772 TransferPipe tp = new TransferPipe();
8773 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08008774 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
8775 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008776 tp.go(fd);
8777 } finally {
8778 tp.kill();
8779 }
8780 } catch (IOException e) {
8781 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008782 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008783 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008784 }
8785 }
8786 }
8787
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008788 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008789 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008790 boolean needSep = false;
8791
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008792 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008793 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008794 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008795 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008796 Iterator it = mRegisteredReceivers.values().iterator();
8797 while (it.hasNext()) {
8798 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008799 if (dumpPackage != null && (r.app == null ||
8800 !dumpPackage.equals(r.app.info.packageName))) {
8801 continue;
8802 }
8803 if (!printed) {
8804 pw.println(" Registered Receivers:");
8805 needSep = true;
8806 printed = true;
8807 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008808 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008809 r.dump(pw, " ");
8810 }
8811 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008812
8813 if (mReceiverResolver.dump(pw, needSep ?
8814 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
8815 " ", dumpPackage, false)) {
8816 needSep = true;
8817 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008818 }
8819
8820 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8821 || mPendingBroadcast != null) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008822 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008823 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008824 BroadcastRecord br = mParallelBroadcasts.get(i);
8825 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8826 continue;
8827 }
8828 if (!printed) {
8829 if (needSep) {
8830 pw.println();
8831 }
8832 needSep = true;
8833 pw.println(" Active broadcasts:");
8834 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008835 pw.println(" Broadcast #" + i + ":");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008836 br.dump(pw, " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008837 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008838 printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008839 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008840 BroadcastRecord br = mOrderedBroadcasts.get(i);
8841 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8842 continue;
8843 }
8844 if (!printed) {
8845 if (needSep) {
8846 pw.println();
8847 }
8848 needSep = true;
8849 pw.println(" Active ordered broadcasts:");
8850 }
8851 pw.println(" Ordered Broadcast #" + i + ":");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008852 mOrderedBroadcasts.get(i).dump(pw, " ");
8853 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008854 if (dumpPackage == null || (mPendingBroadcast != null
8855 && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
8856 if (needSep) {
8857 pw.println();
8858 }
8859 pw.println(" Pending broadcast:");
8860 if (mPendingBroadcast != null) {
8861 mPendingBroadcast.dump(pw, " ");
8862 } else {
8863 pw.println(" (null)");
8864 }
8865 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008866 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008867 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008868
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008869 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008870 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8871 BroadcastRecord r = mBroadcastHistory[i];
8872 if (r == null) {
8873 break;
8874 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008875 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
8876 continue;
8877 }
8878 if (!printed) {
8879 if (needSep) {
8880 pw.println();
8881 }
8882 needSep = true;
8883 pw.println(" Historical broadcasts:");
8884 printed = true;
8885 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008886 if (dumpAll) {
8887 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8888 r.dump(pw, " ");
8889 } else {
8890 if (i >= 50) {
8891 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008892 break;
8893 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008894 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008895 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008896 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008897 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008898
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008899 if (mStickyBroadcasts != null && dumpPackage == null) {
8900 if (needSep) {
8901 pw.println();
8902 }
8903 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008904 pw.println(" Sticky broadcasts:");
8905 StringBuilder sb = new StringBuilder(128);
8906 for (Map.Entry<String, ArrayList<Intent>> ent
8907 : mStickyBroadcasts.entrySet()) {
8908 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008909 if (dumpAll) {
8910 pw.println(":");
8911 ArrayList<Intent> intents = ent.getValue();
8912 final int N = intents.size();
8913 for (int i=0; i<N; i++) {
8914 sb.setLength(0);
8915 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008916 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008917 pw.println(sb.toString());
8918 Bundle bundle = intents.get(i).getExtras();
8919 if (bundle != null) {
8920 pw.print(" ");
8921 pw.println(bundle.toString());
8922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008923 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008924 } else {
8925 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008926 }
8927 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008928 needSep = true;
8929 }
8930
8931 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008932 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008933 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008934 pw.println(" mHandler:");
8935 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008936 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008937 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008938
8939 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008940 }
8941
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008942 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008943 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008944 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008945
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008946 ItemMatcher matcher = new ItemMatcher();
8947 matcher.build(args, opti);
8948
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008949 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8950 if (mServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008951 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008952 long nowReal = SystemClock.elapsedRealtime();
8953 Iterator<ServiceRecord> it = mServices.values().iterator();
8954 needSep = false;
8955 while (it.hasNext()) {
8956 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008957 if (!matcher.match(r, r.name)) {
8958 continue;
8959 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008960 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
8961 continue;
8962 }
8963 if (!printed) {
8964 pw.println(" Active services:");
8965 printed = true;
8966 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008967 if (needSep) {
8968 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008969 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008970 pw.print(" * "); pw.println(r);
8971 if (dumpAll) {
8972 r.dump(pw, " ");
8973 needSep = true;
8974 } else {
8975 pw.print(" app="); pw.println(r.app);
8976 pw.print(" created=");
8977 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8978 pw.print(" started="); pw.print(r.startRequested);
8979 pw.print(" connections="); pw.println(r.connections.size());
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08008980 if (r.connections.size() > 0) {
8981 pw.println(" Connections:");
8982 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
8983 for (int i=0; i<clist.size(); i++) {
8984 ConnectionRecord conn = clist.get(i);
8985 pw.print(" ");
8986 pw.print(conn.binding.intent.intent.getIntent().toShortString(
8987 false, false, false));
8988 pw.print(" -> ");
8989 ProcessRecord proc = conn.binding.client;
8990 pw.println(proc != null ? proc.toShortString() : "null");
8991 }
8992 }
8993 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008994 }
8995 if (dumpClient && r.app != null && r.app.thread != null) {
8996 pw.println(" Client:");
8997 pw.flush();
8998 try {
8999 TransferPipe tp = new TransferPipe();
9000 try {
9001 r.app.thread.dumpService(
9002 tp.getWriteFd().getFileDescriptor(), r, args);
9003 tp.setBufferPrefix(" ");
9004 // Short timeout, since blocking here can
9005 // deadlock with the application.
9006 tp.go(fd, 2000);
9007 } finally {
9008 tp.kill();
9009 }
9010 } catch (IOException e) {
9011 pw.println(" Failure while dumping the service: " + e);
9012 } catch (RemoteException e) {
9013 pw.println(" Got a RemoteException while dumping the service");
9014 }
9015 needSep = true;
9016 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009017 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009018 needSep = printed;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009020
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009021 if (mPendingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009022 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009023 for (int i=0; i<mPendingServices.size(); i++) {
9024 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009025 if (!matcher.match(r, r.name)) {
9026 continue;
9027 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009028 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9029 continue;
9030 }
9031 if (!printed) {
9032 if (needSep) pw.println(" ");
9033 needSep = true;
9034 pw.println(" Pending services:");
9035 printed = true;
9036 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009037 pw.print(" * Pending "); pw.println(r);
9038 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009039 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009040 needSep = true;
9041 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009042
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009043 if (mRestartingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009044 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009045 for (int i=0; i<mRestartingServices.size(); i++) {
9046 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009047 if (!matcher.match(r, r.name)) {
9048 continue;
9049 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009050 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9051 continue;
9052 }
9053 if (!printed) {
9054 if (needSep) pw.println(" ");
9055 needSep = true;
9056 pw.println(" Restarting services:");
9057 printed = true;
9058 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009059 pw.print(" * Restarting "); pw.println(r);
9060 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009061 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009062 needSep = true;
9063 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009064
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009065 if (mStoppingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009066 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009067 for (int i=0; i<mStoppingServices.size(); i++) {
9068 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009069 if (!matcher.match(r, r.name)) {
9070 continue;
9071 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009072 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9073 continue;
9074 }
9075 if (!printed) {
9076 if (needSep) pw.println(" ");
9077 needSep = true;
9078 pw.println(" Stopping services:");
9079 printed = true;
9080 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009081 pw.print(" * Stopping "); pw.println(r);
9082 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009083 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009084 needSep = true;
9085 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009086
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009087 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009088 if (mServiceConnections.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009089 boolean printed = false;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009090 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009091 = mServiceConnections.values().iterator();
9092 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009093 ArrayList<ConnectionRecord> r = it.next();
9094 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009095 ConnectionRecord cr = r.get(i);
9096 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9097 continue;
9098 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009099 if (dumpPackage != null && (cr.binding.client == null
9100 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9101 continue;
9102 }
9103 if (!printed) {
9104 if (needSep) pw.println(" ");
9105 needSep = true;
9106 pw.println(" Connection bindings to services:");
9107 printed = true;
9108 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009109 pw.print(" * "); pw.println(cr);
9110 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009111 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009112 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009113 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009114 }
9115 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009116
9117 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009118 }
9119
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009120 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009121 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009122 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009123
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009124 ItemMatcher matcher = new ItemMatcher();
9125 matcher.build(args, opti);
9126
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009127 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9128 if (mProvidersByClass.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009129 boolean printed = false;
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009130 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009131 = mProvidersByClass.entrySet().iterator();
9132 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009133 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009134 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009135 ComponentName comp = e.getKey();
9136 String cls = comp.getClassName();
9137 int end = cls.lastIndexOf('.');
9138 if (end > 0 && end < (cls.length()-2)) {
9139 cls = cls.substring(end+1);
9140 }
9141 if (!matcher.match(r, comp)) {
9142 continue;
9143 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009144 if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) {
9145 continue;
9146 }
9147 if (!printed) {
9148 if (needSep) pw.println(" ");
9149 needSep = true;
9150 pw.println(" Published content providers (by class):");
9151 printed = true;
9152 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009153 pw.print(" * "); pw.print(cls); pw.print(" (");
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009154 pw.print(comp.flattenToShortString()); pw.println(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009155 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009156 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009157 } else {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009158 if (r.proc != null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009159 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009160 } else {
9161 pw.println();
9162 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009163 if (r.clients.size() > 0) {
9164 pw.println(" Clients:");
9165 for (ProcessRecord cproc : r.clients) {
9166 pw.print(" - "); pw.println(cproc);
9167 }
9168 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009169 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009170 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009171 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009172
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009173 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009174 if (mProvidersByName.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009175 boolean printed = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -07009176 Iterator<Map.Entry<String, ContentProviderRecord>> it
9177 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009178 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009179 Map.Entry<String, ContentProviderRecord> e = it.next();
9180 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009181 if (!matcher.match(r, r.name)) {
9182 continue;
9183 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009184 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9185 continue;
9186 }
9187 if (!printed) {
9188 if (needSep) pw.println(" ");
9189 needSep = true;
9190 pw.println(" Authority to provider mappings:");
9191 printed = true;
9192 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009193 pw.print(" "); pw.print(e.getKey()); pw.println(":");
9194 pw.print(" "); pw.println(r);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009195 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009196 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009197 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009198
9199 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009200 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009201 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009202 ContentProviderRecord r = mLaunchingProviders.get(i);
9203 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9204 continue;
9205 }
9206 if (!printed) {
9207 if (needSep) pw.println(" ");
9208 needSep = true;
9209 pw.println(" Launching content providers:");
9210 printed = true;
9211 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009212 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009213 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009214 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009215 }
9216
9217 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009218 if (needSep) pw.println();
9219 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009220 pw.println("Granted Uri Permissions:");
9221 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9222 int uid = mGrantedUriPermissions.keyAt(i);
9223 HashMap<Uri, UriPermission> perms
9224 = mGrantedUriPermissions.valueAt(i);
9225 pw.print(" * UID "); pw.print(uid);
9226 pw.println(" holds:");
9227 for (UriPermission perm : perms.values()) {
9228 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009229 if (dumpAll) {
9230 perm.dump(pw, " ");
9231 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009232 }
9233 }
9234 needSep = true;
9235 }
9236
9237 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009238 }
9239
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009240 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009241 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009242 boolean needSep = false;
9243
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009244 if (mIntentSenderRecords.size() > 0) {
9245 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009246 Iterator<WeakReference<PendingIntentRecord>> it
9247 = mIntentSenderRecords.values().iterator();
9248 while (it.hasNext()) {
9249 WeakReference<PendingIntentRecord> ref = it.next();
9250 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009251 if (dumpPackage != null && (rec == null
9252 || !dumpPackage.equals(rec.key.packageName))) {
9253 continue;
9254 }
9255 if (!printed) {
9256 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9257 printed = true;
9258 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009259 needSep = true;
9260 if (rec != null) {
9261 pw.print(" * "); pw.println(rec);
9262 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009263 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009264 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009265 } else {
9266 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009267 }
9268 }
9269 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009270
9271 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009272 }
9273
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009274 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009275 String prefix, String label, boolean complete, boolean brief, boolean client,
9276 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009277 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009278 boolean needNL = false;
9279 final String innerPrefix = prefix + " ";
9280 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009281 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009282 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009283 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9284 continue;
9285 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07009286 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009287 if (needNL) {
9288 pw.println(" ");
9289 needNL = false;
9290 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009291 if (lastTask != r.task) {
9292 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009293 pw.print(prefix);
9294 pw.print(full ? "* " : " ");
9295 pw.println(lastTask);
9296 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009297 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009298 } else if (complete) {
9299 // Complete + brief == give a summary. Isn't that obvious?!?
9300 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009301 pw.print(prefix); pw.print(" ");
9302 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009303 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009305 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009306 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
9307 pw.print(" #"); pw.print(i); pw.print(": ");
9308 pw.println(r);
9309 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009310 r.dump(pw, innerPrefix);
9311 } else if (complete) {
9312 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009313 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009314 if (r.app != null) {
9315 pw.print(innerPrefix); pw.println(r.app);
9316 }
9317 }
9318 if (client && r.app != null && r.app.thread != null) {
9319 // flush anything that is already in the PrintWriter since the thread is going
9320 // to write to the file descriptor directly
9321 pw.flush();
9322 try {
9323 TransferPipe tp = new TransferPipe();
9324 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009325 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9326 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009327 // Short timeout, since blocking here can
9328 // deadlock with the application.
9329 tp.go(fd, 2000);
9330 } finally {
9331 tp.kill();
9332 }
9333 } catch (IOException e) {
9334 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9335 } catch (RemoteException e) {
9336 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9337 }
9338 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009339 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009340 }
9341 }
9342
Dianne Hackborn09c916b2009-12-08 14:50:51 -08009343 private static String buildOomTag(String prefix, String space, int val, int base) {
9344 if (val == base) {
9345 if (space == null) return prefix;
9346 return prefix + " ";
9347 }
9348 return prefix + "+" + Integer.toString(val-base);
9349 }
9350
9351 private static final int dumpProcessList(PrintWriter pw,
9352 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009353 String prefix, String normalLabel, String persistentLabel,
9354 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009355 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009356 final int N = list.size()-1;
9357 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009358 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009359 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9360 continue;
9361 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009362 pw.println(String.format("%s%s #%2d: %s",
9363 prefix, (r.persistent ? persistentLabel : normalLabel),
9364 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009365 if (r.persistent) {
9366 numPers++;
9367 }
9368 }
9369 return numPers;
9370 }
9371
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009372 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07009373 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009374 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009375 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009376
Dianne Hackborn905577f2011-09-07 18:31:28 -07009377 ArrayList<Pair<ProcessRecord, Integer>> list
9378 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9379 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009380 ProcessRecord r = origList.get(i);
9381 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9382 continue;
9383 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07009384 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9385 }
9386
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009387 if (list.size() <= 0) {
9388 return false;
9389 }
9390
Dianne Hackborn905577f2011-09-07 18:31:28 -07009391 Comparator<Pair<ProcessRecord, Integer>> comparator
9392 = new Comparator<Pair<ProcessRecord, Integer>>() {
9393 @Override
9394 public int compare(Pair<ProcessRecord, Integer> object1,
9395 Pair<ProcessRecord, Integer> object2) {
9396 if (object1.first.setAdj != object2.first.setAdj) {
9397 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9398 }
9399 if (object1.second.intValue() != object2.second.intValue()) {
9400 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9401 }
9402 return 0;
9403 }
9404 };
9405
9406 Collections.sort(list, comparator);
9407
Dianne Hackborn287952c2010-09-22 22:34:31 -07009408 final long curRealtime = SystemClock.elapsedRealtime();
9409 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9410 final long curUptime = SystemClock.uptimeMillis();
9411 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9412
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009413 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07009414 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009415 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009416 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009417 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009418 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9419 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009420 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9421 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009422 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9423 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009424 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9425 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009426 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009427 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009428 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9429 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9430 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9431 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9432 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9433 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9434 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9435 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009436 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9437 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009438 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9439 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009440 } else {
9441 oomAdj = Integer.toString(r.setAdj);
9442 }
9443 String schedGroup;
9444 switch (r.setSchedGroup) {
9445 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9446 schedGroup = "B";
9447 break;
9448 case Process.THREAD_GROUP_DEFAULT:
9449 schedGroup = "F";
9450 break;
9451 default:
9452 schedGroup = Integer.toString(r.setSchedGroup);
9453 break;
9454 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009455 String foreground;
9456 if (r.foregroundActivities) {
9457 foreground = "A";
9458 } else if (r.foregroundServices) {
9459 foreground = "S";
9460 } else {
9461 foreground = " ";
9462 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009463 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009464 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009465 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9466 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009467 if (r.adjSource != null || r.adjTarget != null) {
9468 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009469 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009470 if (r.adjTarget instanceof ComponentName) {
9471 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9472 } else if (r.adjTarget != null) {
9473 pw.print(r.adjTarget.toString());
9474 } else {
9475 pw.print("{null}");
9476 }
9477 pw.print("<=");
9478 if (r.adjSource instanceof ProcessRecord) {
9479 pw.print("Proc{");
9480 pw.print(((ProcessRecord)r.adjSource).toShortString());
9481 pw.println("}");
9482 } else if (r.adjSource != null) {
9483 pw.println(r.adjSource.toString());
9484 } else {
9485 pw.println("{null}");
9486 }
9487 }
9488 if (inclDetails) {
9489 pw.print(prefix);
9490 pw.print(" ");
9491 pw.print("oom: max="); pw.print(r.maxAdj);
9492 pw.print(" hidden="); pw.print(r.hiddenAdj);
9493 pw.print(" curRaw="); pw.print(r.curRawAdj);
9494 pw.print(" setRaw="); pw.print(r.setRawAdj);
9495 pw.print(" cur="); pw.print(r.curAdj);
9496 pw.print(" set="); pw.println(r.setAdj);
9497 pw.print(prefix);
9498 pw.print(" ");
9499 pw.print("keeping="); pw.print(r.keeping);
9500 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009501 pw.print(" empty="); pw.print(r.empty);
9502 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009503
9504 if (!r.keeping) {
9505 if (r.lastWakeTime != 0) {
9506 long wtime;
9507 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9508 synchronized (stats) {
9509 wtime = stats.getProcessWakeTime(r.info.uid,
9510 r.pid, curRealtime);
9511 }
9512 long timeUsed = wtime - r.lastWakeTime;
9513 pw.print(prefix);
9514 pw.print(" ");
9515 pw.print("keep awake over ");
9516 TimeUtils.formatDuration(realtimeSince, pw);
9517 pw.print(" used ");
9518 TimeUtils.formatDuration(timeUsed, pw);
9519 pw.print(" (");
9520 pw.print((timeUsed*100)/realtimeSince);
9521 pw.println("%)");
9522 }
9523 if (r.lastCpuTime != 0) {
9524 long timeUsed = r.curCpuTime - r.lastCpuTime;
9525 pw.print(prefix);
9526 pw.print(" ");
9527 pw.print("run cpu over ");
9528 TimeUtils.formatDuration(uptimeSince, pw);
9529 pw.print(" used ");
9530 TimeUtils.formatDuration(timeUsed, pw);
9531 pw.print(" (");
9532 pw.print((timeUsed*100)/uptimeSince);
9533 pw.println("%)");
9534 }
9535 }
9536 }
9537 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009538 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009539 }
9540
Dianne Hackbornb437e092011-08-05 17:50:29 -07009541 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009542 ArrayList<ProcessRecord> procs;
9543 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009544 if (args != null && args.length > start
9545 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009546 procs = new ArrayList<ProcessRecord>();
9547 int pid = -1;
9548 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009549 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009550 } catch (NumberFormatException e) {
9551
9552 }
9553 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9554 ProcessRecord proc = mLruProcesses.get(i);
9555 if (proc.pid == pid) {
9556 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009557 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009558 procs.add(proc);
9559 }
9560 }
9561 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009562 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009563 return null;
9564 }
9565 } else {
9566 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9567 }
9568 }
9569 return procs;
9570 }
9571
9572 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9573 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009574 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009575 if (procs == null) {
9576 return;
9577 }
9578
9579 long uptime = SystemClock.uptimeMillis();
9580 long realtime = SystemClock.elapsedRealtime();
9581 pw.println("Applications Graphics Acceleration Info:");
9582 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9583
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009584 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9585 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009586 if (r.thread != null) {
9587 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9588 pw.flush();
9589 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009590 TransferPipe tp = new TransferPipe();
9591 try {
9592 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9593 tp.go(fd);
9594 } finally {
9595 tp.kill();
9596 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009597 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009598 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009599 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009600 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009601 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009602 pw.flush();
9603 }
9604 }
9605 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009606 }
9607
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009608 final static class MemItem {
9609 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009610 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009611 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009612 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009613 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009614
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009615 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009616 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009617 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009618 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009619 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009620 }
9621 }
9622
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009623 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -07009624 boolean sort) {
9625 if (sort) {
9626 Collections.sort(items, new Comparator<MemItem>() {
9627 @Override
9628 public int compare(MemItem lhs, MemItem rhs) {
9629 if (lhs.pss < rhs.pss) {
9630 return 1;
9631 } else if (lhs.pss > rhs.pss) {
9632 return -1;
9633 }
9634 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009635 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009636 });
9637 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009638
9639 for (int i=0; i<items.size(); i++) {
9640 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009641 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009642 if (mi.subitems != null) {
9643 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9644 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009645 }
9646 }
9647
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009648 // These are in KB.
9649 static final long[] DUMP_MEM_BUCKETS = new long[] {
9650 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9651 120*1024, 160*1024, 200*1024,
9652 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9653 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9654 };
9655
Dianne Hackborn672342c2011-11-29 11:29:02 -08009656 static final void appendMemBucket(StringBuilder out, long memKB, String label,
9657 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009658 int start = label.lastIndexOf('.');
9659 if (start >= 0) start++;
9660 else start = 0;
9661 int end = label.length();
9662 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9663 if (DUMP_MEM_BUCKETS[i] >= memKB) {
9664 long bucket = DUMP_MEM_BUCKETS[i]/1024;
9665 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -08009666 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009667 out.append(label, start, end);
9668 return;
9669 }
9670 }
9671 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08009672 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009673 out.append(label, start, end);
9674 }
9675
9676 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9677 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9678 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9679 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9680 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9681 };
9682 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9683 "System", "Persistent", "Foreground",
9684 "Visible", "Perceptible", "Heavy Weight",
9685 "Backup", "A Services", "Home", "Previous",
9686 "B Services", "Background"
9687 };
9688
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009689 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009690 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -08009691 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009692 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009693 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009694
9695 int opti = 0;
9696 while (opti < args.length) {
9697 String opt = args[opti];
9698 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9699 break;
9700 }
9701 opti++;
9702 if ("-a".equals(opt)) {
9703 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009704 } else if ("--oom".equals(opt)) {
9705 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009706 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009707 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009708 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009709 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009710 pw.println("If [process] is specified it can be the name or ");
9711 pw.println("pid of a specific process to dump.");
9712 return;
9713 } else {
9714 pw.println("Unknown argument: " + opt + "; use -h for help");
9715 }
9716 }
9717
9718 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009719 if (procs == null) {
9720 return;
9721 }
9722
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009723 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009724 long uptime = SystemClock.uptimeMillis();
9725 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009726
9727 if (procs.size() == 1 || isCheckinRequest) {
9728 dumpAll = true;
9729 }
9730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009731 if (isCheckinRequest) {
9732 // short checkin version
9733 pw.println(uptime + "," + realtime);
9734 pw.flush();
9735 } else {
9736 pw.println("Applications Memory Usage (kB):");
9737 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9738 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009739
Dianne Hackbornb437e092011-08-05 17:50:29 -07009740 String[] innerArgs = new String[args.length-opti];
9741 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9742
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009743 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9744 long nativePss=0, dalvikPss=0, otherPss=0;
9745 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9746
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009747 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
9748 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
9749 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009750
9751 long totalPss = 0;
9752
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009753 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9754 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009755 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009756 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009757 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9758 pw.flush();
9759 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009760 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009761 if (dumpAll) {
9762 try {
9763 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9764 } catch (RemoteException e) {
9765 if (!isCheckinRequest) {
9766 pw.println("Got RemoteException!");
9767 pw.flush();
9768 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009769 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009770 } else {
9771 mi = new Debug.MemoryInfo();
9772 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009773 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009774
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009775 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009776 long myTotalPss = mi.getTotalPss();
9777 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009778 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009779 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009780 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009781
9782 nativePss += mi.nativePss;
9783 dalvikPss += mi.dalvikPss;
9784 otherPss += mi.otherPss;
9785 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9786 long mem = mi.getOtherPss(j);
9787 miscPss[j] += mem;
9788 otherPss -= mem;
9789 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009790
9791 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009792 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
9793 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009794 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009795 if (oomProcs[oomIndex] == null) {
9796 oomProcs[oomIndex] = new ArrayList<MemItem>();
9797 }
9798 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009799 break;
9800 }
9801 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009802 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009803 }
9804 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009805
9806 if (!isCheckinRequest && procs.size() > 1) {
9807 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9808
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009809 catMems.add(new MemItem("Native", "Native", nativePss, -1));
9810 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
9811 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009812 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009813 String label = Debug.MemoryInfo.getOtherLabel(j);
9814 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009815 }
9816
Dianne Hackbornb437e092011-08-05 17:50:29 -07009817 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9818 for (int j=0; j<oomPss.length; j++) {
9819 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009820 String label = DUMP_MEM_OOM_LABEL[j];
9821 MemItem item = new MemItem(label, label, oomPss[j],
9822 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009823 item.subitems = oomProcs[j];
9824 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009825 }
9826 }
9827
Dianne Hackborn672342c2011-11-29 11:29:02 -08009828 if (outTag != null || outStack != null) {
9829 if (outTag != null) {
9830 appendMemBucket(outTag, totalPss, "total", false);
9831 }
9832 if (outStack != null) {
9833 appendMemBucket(outStack, totalPss, "total", true);
9834 }
9835 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009836 for (int i=0; i<oomMems.size(); i++) {
9837 MemItem miCat = oomMems.get(i);
9838 if (miCat.subitems == null || miCat.subitems.size() < 1) {
9839 continue;
9840 }
9841 if (miCat.id < ProcessList.SERVICE_ADJ
9842 || miCat.id == ProcessList.HOME_APP_ADJ
9843 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009844 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
9845 outTag.append(" / ");
9846 }
9847 if (outStack != null) {
9848 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
9849 if (firstLine) {
9850 outStack.append(":");
9851 firstLine = false;
9852 }
9853 outStack.append("\n\t at ");
9854 } else {
9855 outStack.append("$");
9856 }
9857 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009858 for (int j=0; j<miCat.subitems.size(); j++) {
9859 MemItem mi = miCat.subitems.get(j);
9860 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009861 if (outTag != null) {
9862 outTag.append(" ");
9863 }
9864 if (outStack != null) {
9865 outStack.append("$");
9866 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009867 }
Dianne Hackborn672342c2011-11-29 11:29:02 -08009868 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
9869 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
9870 }
9871 if (outStack != null) {
9872 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
9873 }
9874 }
9875 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
9876 outStack.append("(");
9877 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
9878 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
9879 outStack.append(DUMP_MEM_OOM_LABEL[k]);
9880 outStack.append(":");
9881 outStack.append(DUMP_MEM_OOM_ADJ[k]);
9882 }
9883 }
9884 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009885 }
9886 }
9887 }
9888 }
9889
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009890 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009891 pw.println();
9892 pw.println("Total PSS by process:");
9893 dumpMemItems(pw, " ", procMems, true);
9894 pw.println();
9895 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009896 pw.println("Total PSS by OOM adjustment:");
9897 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009898 if (!oomOnly) {
9899 PrintWriter out = categoryPw != null ? categoryPw : pw;
9900 out.println();
9901 out.println("Total PSS by category:");
9902 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009903 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009904 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009905 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009906 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009907 }
9908
9909 /**
9910 * Searches array of arguments for the specified string
9911 * @param args array of argument strings
9912 * @param value value to search for
9913 * @return true if the value is contained in the array
9914 */
9915 private static boolean scanArgs(String[] args, String value) {
9916 if (args != null) {
9917 for (String arg : args) {
9918 if (value.equals(arg)) {
9919 return true;
9920 }
9921 }
9922 }
9923 return false;
9924 }
9925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009926 private final void killServicesLocked(ProcessRecord app,
9927 boolean allowRestart) {
9928 // Report disconnected services.
9929 if (false) {
9930 // XXX we are letting the client link to the service for
9931 // death notifications.
9932 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009933 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009934 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009935 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009936 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009937 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009938 = r.connections.values().iterator();
9939 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009940 ArrayList<ConnectionRecord> cl = jt.next();
9941 for (int i=0; i<cl.size(); i++) {
9942 ConnectionRecord c = cl.get(i);
9943 if (c.binding.client != app) {
9944 try {
9945 //c.conn.connected(r.className, null);
9946 } catch (Exception e) {
9947 // todo: this should be asynchronous!
9948 Slog.w(TAG, "Exception thrown disconnected servce "
9949 + r.shortName
9950 + " from app " + app.processName, e);
9951 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009952 }
9953 }
9954 }
9955 }
9956 }
9957 }
9958 }
9959
9960 // Clean up any connections this application has to other services.
9961 if (app.connections.size() > 0) {
9962 Iterator<ConnectionRecord> it = app.connections.iterator();
9963 while (it.hasNext()) {
9964 ConnectionRecord r = it.next();
9965 removeConnectionLocked(r, app, null);
9966 }
9967 }
9968 app.connections.clear();
9969
9970 if (app.services.size() != 0) {
9971 // Any services running in the application need to be placed
9972 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009973 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009974 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009975 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009976 synchronized (sr.stats.getBatteryStats()) {
9977 sr.stats.stopLaunchedLocked();
9978 }
9979 sr.app = null;
9980 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009981 if (mStoppingServices.remove(sr)) {
9982 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9983 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009984
9985 boolean hasClients = sr.bindings.size() > 0;
9986 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009987 Iterator<IntentBindRecord> bindings
9988 = sr.bindings.values().iterator();
9989 while (bindings.hasNext()) {
9990 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009991 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009992 + ": shouldUnbind=" + b.hasBound);
9993 b.binder = null;
9994 b.requested = b.received = b.hasBound = false;
9995 }
9996 }
9997
Dianne Hackborn070783f2010-12-29 16:46:28 -08009998 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9999 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010000 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010001 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010002 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010003 sr.crashCount, sr.shortName, app.pid);
10004 bringDownServiceLocked(sr, true);
10005 } else if (!allowRestart) {
10006 bringDownServiceLocked(sr, true);
10007 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010008 boolean canceled = scheduleServiceRestartLocked(sr, true);
10009
10010 // Should the service remain running? Note that in the
10011 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010012 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010013 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10014 if (sr.pendingStarts.size() == 0) {
10015 sr.startRequested = false;
10016 if (!hasClients) {
10017 // Whoops, no reason to restart!
10018 bringDownServiceLocked(sr, true);
10019 }
10020 }
10021 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010022 }
10023 }
10024
10025 if (!allowRestart) {
10026 app.services.clear();
10027 }
10028 }
10029
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010030 // Make sure we have no more records on the stopping list.
10031 int i = mStoppingServices.size();
10032 while (i > 0) {
10033 i--;
10034 ServiceRecord sr = mStoppingServices.get(i);
10035 if (sr.app == app) {
10036 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010037 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010038 }
10039 }
10040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010041 app.executingServices.clear();
10042 }
10043
10044 private final void removeDyingProviderLocked(ProcessRecord proc,
10045 ContentProviderRecord cpr) {
10046 synchronized (cpr) {
10047 cpr.launchingApp = null;
10048 cpr.notifyAll();
10049 }
10050
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010051 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010052 String names[] = cpr.info.authority.split(";");
10053 for (int j = 0; j < names.length; j++) {
10054 mProvidersByName.remove(names[j]);
10055 }
10056
10057 Iterator<ProcessRecord> cit = cpr.clients.iterator();
10058 while (cit.hasNext()) {
10059 ProcessRecord capp = cit.next();
10060 if (!capp.persistent && capp.thread != null
10061 && capp.pid != 0
10062 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010063 Slog.i(TAG, "Kill " + capp.processName
10064 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010065 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -070010066 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010067 capp.processName, capp.setAdj, "dying provider "
10068 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010069 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010070 }
10071 }
10072
10073 mLaunchingProviders.remove(cpr);
10074 }
10075
10076 /**
10077 * Main code for cleaning up a process when it has gone away. This is
10078 * called both as a result of the process dying, or directly when stopping
10079 * a process when running in single process mode.
10080 */
10081 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010082 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010083 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010084 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010085 }
10086
Dianne Hackborn36124872009-10-08 16:22:03 -070010087 mProcessesToGc.remove(app);
10088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010089 // Dismiss any open dialogs.
10090 if (app.crashDialog != null) {
10091 app.crashDialog.dismiss();
10092 app.crashDialog = null;
10093 }
10094 if (app.anrDialog != null) {
10095 app.anrDialog.dismiss();
10096 app.anrDialog = null;
10097 }
10098 if (app.waitDialog != null) {
10099 app.waitDialog.dismiss();
10100 app.waitDialog = null;
10101 }
10102
10103 app.crashing = false;
10104 app.notResponding = false;
10105
10106 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070010107 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010108 app.thread = null;
10109 app.forcingToForeground = null;
10110 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010111 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070010112 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010113 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010114
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010115 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010116
10117 boolean restart = false;
10118
10119 int NL = mLaunchingProviders.size();
10120
10121 // Remove published content providers.
10122 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010123 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010124 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010125 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010126 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010127 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010128
10129 // See if someone is waiting for this provider... in which
10130 // case we don't remove it, but just let it restart.
10131 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010132 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010133 for (; i<NL; i++) {
10134 if (mLaunchingProviders.get(i) == cpr) {
10135 restart = true;
10136 break;
10137 }
10138 }
10139 } else {
10140 i = NL;
10141 }
10142
10143 if (i >= NL) {
10144 removeDyingProviderLocked(app, cpr);
10145 NL = mLaunchingProviders.size();
10146 }
10147 }
10148 app.pubProviders.clear();
10149 }
10150
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010151 // Take care of any launching providers waiting for this process.
10152 if (checkAppInLaunchingProvidersLocked(app, false)) {
10153 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010154 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010156 // Unregister from connected content providers.
10157 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -070010158 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010159 while (it.hasNext()) {
10160 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10161 cpr.clients.remove(app);
10162 }
10163 app.conProviders.clear();
10164 }
10165
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010166 // At this point there may be remaining entries in mLaunchingProviders
10167 // where we were the only one waiting, so they are no longer of use.
10168 // Look for these and clean up if found.
10169 // XXX Commented out for now. Trying to figure out a way to reproduce
10170 // the actual situation to identify what is actually going on.
10171 if (false) {
10172 for (int i=0; i<NL; i++) {
10173 ContentProviderRecord cpr = (ContentProviderRecord)
10174 mLaunchingProviders.get(i);
10175 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
10176 synchronized (cpr) {
10177 cpr.launchingApp = null;
10178 cpr.notifyAll();
10179 }
10180 }
10181 }
10182 }
10183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010184 skipCurrentReceiverLocked(app);
10185
10186 // Unregister any receivers.
10187 if (app.receivers.size() > 0) {
10188 Iterator<ReceiverList> it = app.receivers.iterator();
10189 while (it.hasNext()) {
10190 removeReceiverLocked(it.next());
10191 }
10192 app.receivers.clear();
10193 }
10194
Christopher Tate181fafa2009-05-14 11:12:14 -070010195 // If the app is undergoing backup, tell the backup manager about it
10196 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010197 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070010198 try {
10199 IBackupManager bm = IBackupManager.Stub.asInterface(
10200 ServiceManager.getService(Context.BACKUP_SERVICE));
10201 bm.agentDisconnected(app.info.packageName);
10202 } catch (RemoteException e) {
10203 // can't happen; backup manager is local
10204 }
10205 }
10206
Jeff Sharkey287bd832011-05-28 19:36:26 -070010207 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010209 // If the caller is restarting this app, then leave it in its
10210 // current lists and let the caller take care of it.
10211 if (restarting) {
10212 return;
10213 }
10214
10215 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010216 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010217 "Removing non-persistent process during cleanup: " + app);
10218 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070010219 if (mHeavyWeightProcess == app) {
10220 mHeavyWeightProcess = null;
10221 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10222 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010223 } else if (!app.removed) {
10224 // This app is persistent, so we need to keep its record around.
10225 // If it is not already on the pending app list, add it there
10226 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010227 if (mPersistentStartingProcesses.indexOf(app) < 0) {
10228 mPersistentStartingProcesses.add(app);
10229 restart = true;
10230 }
10231 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010232 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10233 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010234 mProcessesOnHold.remove(app);
10235
The Android Open Source Project4df24232009-03-05 14:34:35 -080010236 if (app == mHomeProcess) {
10237 mHomeProcess = null;
10238 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010239 if (app == mPreviousProcess) {
10240 mPreviousProcess = null;
10241 }
10242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010243 if (restart) {
10244 // We have components that still need to be running in the
10245 // process, so re-launch it.
10246 mProcessNames.put(app.processName, app.info.uid, app);
10247 startProcessLocked(app, "restart", app.processName);
10248 } else if (app.pid > 0 && app.pid != MY_PID) {
10249 // Goodbye!
10250 synchronized (mPidsSelfLocked) {
10251 mPidsSelfLocked.remove(app.pid);
10252 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10253 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010254 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010255 }
10256 }
10257
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010258 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10259 // Look through the content providers we are waiting to have launched,
10260 // and if any run in this process then either schedule a restart of
10261 // the process or kill the client waiting for it if this process has
10262 // gone bad.
10263 int NL = mLaunchingProviders.size();
10264 boolean restart = false;
10265 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010266 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010267 if (cpr.launchingApp == app) {
10268 if (!alwaysBad && !app.bad) {
10269 restart = true;
10270 } else {
10271 removeDyingProviderLocked(app, cpr);
10272 NL = mLaunchingProviders.size();
10273 }
10274 }
10275 }
10276 return restart;
10277 }
10278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010279 // =========================================================
10280 // SERVICES
10281 // =========================================================
10282
10283 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10284 ActivityManager.RunningServiceInfo info =
10285 new ActivityManager.RunningServiceInfo();
10286 info.service = r.name;
10287 if (r.app != null) {
10288 info.pid = r.app.pid;
10289 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010290 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010291 info.process = r.processName;
10292 info.foreground = r.isForeground;
10293 info.activeSince = r.createTime;
10294 info.started = r.startRequested;
10295 info.clientCount = r.connections.size();
10296 info.crashCount = r.crashCount;
10297 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010298 if (r.isForeground) {
10299 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10300 }
10301 if (r.startRequested) {
10302 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10303 }
Dan Egnor42471dd2010-01-07 17:25:22 -080010304 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010305 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10306 }
10307 if (r.app != null && r.app.persistent) {
10308 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10309 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010310
10311 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10312 for (int i=0; i<connl.size(); i++) {
10313 ConnectionRecord conn = connl.get(i);
10314 if (conn.clientLabel != 0) {
10315 info.clientPackage = conn.binding.client.info.packageName;
10316 info.clientLabel = conn.clientLabel;
10317 return info;
10318 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010319 }
10320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010321 return info;
10322 }
10323
10324 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10325 int flags) {
10326 synchronized (this) {
10327 ArrayList<ActivityManager.RunningServiceInfo> res
10328 = new ArrayList<ActivityManager.RunningServiceInfo>();
10329
10330 if (mServices.size() > 0) {
10331 Iterator<ServiceRecord> it = mServices.values().iterator();
10332 while (it.hasNext() && res.size() < maxNum) {
10333 res.add(makeRunningServiceInfoLocked(it.next()));
10334 }
10335 }
10336
10337 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10338 ServiceRecord r = mRestartingServices.get(i);
10339 ActivityManager.RunningServiceInfo info =
10340 makeRunningServiceInfoLocked(r);
10341 info.restarting = r.nextRestartTime;
10342 res.add(info);
10343 }
10344
10345 return res;
10346 }
10347 }
10348
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010349 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10350 synchronized (this) {
10351 ServiceRecord r = mServices.get(name);
10352 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010353 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
10354 for (int i=0; i<conn.size(); i++) {
10355 if (conn.get(i).clientIntent != null) {
10356 return conn.get(i).clientIntent;
10357 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010358 }
10359 }
10360 }
10361 }
10362 return null;
10363 }
10364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010365 private final ServiceRecord findServiceLocked(ComponentName name,
10366 IBinder token) {
10367 ServiceRecord r = mServices.get(name);
10368 return r == token ? r : null;
10369 }
10370
10371 private final class ServiceLookupResult {
10372 final ServiceRecord record;
10373 final String permission;
10374
10375 ServiceLookupResult(ServiceRecord _record, String _permission) {
10376 record = _record;
10377 permission = _permission;
10378 }
10379 };
10380
10381 private ServiceLookupResult findServiceLocked(Intent service,
10382 String resolvedType) {
10383 ServiceRecord r = null;
10384 if (service.getComponent() != null) {
10385 r = mServices.get(service.getComponent());
10386 }
10387 if (r == null) {
10388 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10389 r = mServicesByIntent.get(filter);
10390 }
10391
10392 if (r == null) {
10393 try {
10394 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010395 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010396 service, resolvedType, 0);
10397 ServiceInfo sInfo =
10398 rInfo != null ? rInfo.serviceInfo : null;
10399 if (sInfo == null) {
10400 return null;
10401 }
10402
10403 ComponentName name = new ComponentName(
10404 sInfo.applicationInfo.packageName, sInfo.name);
10405 r = mServices.get(name);
10406 } catch (RemoteException ex) {
10407 // pm is in same process, this will never happen.
10408 }
10409 }
10410 if (r != null) {
10411 int callingPid = Binder.getCallingPid();
10412 int callingUid = Binder.getCallingUid();
10413 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010414 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010415 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010416 if (!r.exported) {
10417 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10418 + " from pid=" + callingPid
10419 + ", uid=" + callingUid
10420 + " that is not exported from uid " + r.appInfo.uid);
10421 return new ServiceLookupResult(null, "not exported from uid "
10422 + r.appInfo.uid);
10423 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010424 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010425 + " from pid=" + callingPid
10426 + ", uid=" + callingUid
10427 + " requires " + r.permission);
10428 return new ServiceLookupResult(null, r.permission);
10429 }
10430 return new ServiceLookupResult(r, null);
10431 }
10432 return null;
10433 }
10434
10435 private class ServiceRestarter implements Runnable {
10436 private ServiceRecord mService;
10437
10438 void setService(ServiceRecord service) {
10439 mService = service;
10440 }
10441
10442 public void run() {
10443 synchronized(ActivityManagerService.this) {
10444 performServiceRestartLocked(mService);
10445 }
10446 }
10447 }
10448
10449 private ServiceLookupResult retrieveServiceLocked(Intent service,
10450 String resolvedType, int callingPid, int callingUid) {
10451 ServiceRecord r = null;
10452 if (service.getComponent() != null) {
10453 r = mServices.get(service.getComponent());
10454 }
10455 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10456 r = mServicesByIntent.get(filter);
10457 if (r == null) {
10458 try {
10459 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010460 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010461 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010462 ServiceInfo sInfo =
10463 rInfo != null ? rInfo.serviceInfo : null;
10464 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010465 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010466 ": not found");
10467 return null;
10468 }
10469
10470 ComponentName name = new ComponentName(
10471 sInfo.applicationInfo.packageName, sInfo.name);
10472 r = mServices.get(name);
10473 if (r == null) {
10474 filter = new Intent.FilterComparison(service.cloneFilter());
10475 ServiceRestarter res = new ServiceRestarter();
10476 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10477 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10478 synchronized (stats) {
10479 ss = stats.getServiceStatsLocked(
10480 sInfo.applicationInfo.uid, sInfo.packageName,
10481 sInfo.name);
10482 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080010483 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010484 res.setService(r);
10485 mServices.put(name, r);
10486 mServicesByIntent.put(filter, r);
10487
10488 // Make sure this component isn't in the pending list.
10489 int N = mPendingServices.size();
10490 for (int i=0; i<N; i++) {
10491 ServiceRecord pr = mPendingServices.get(i);
10492 if (pr.name.equals(name)) {
10493 mPendingServices.remove(i);
10494 i--;
10495 N--;
10496 }
10497 }
10498 }
10499 } catch (RemoteException ex) {
10500 // pm is in same process, this will never happen.
10501 }
10502 }
10503 if (r != null) {
10504 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010505 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010506 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010507 if (!r.exported) {
10508 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10509 + " from pid=" + callingPid
10510 + ", uid=" + callingUid
10511 + " that is not exported from uid " + r.appInfo.uid);
10512 return new ServiceLookupResult(null, "not exported from uid "
10513 + r.appInfo.uid);
10514 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010515 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010516 + " from pid=" + callingPid
10517 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010518 + " requires " + r.permission);
10519 return new ServiceLookupResult(null, r.permission);
10520 }
10521 return new ServiceLookupResult(r, null);
10522 }
10523 return null;
10524 }
10525
Dianne Hackborn287952c2010-09-22 22:34:31 -070010526 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
10527 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
10528 + why + " of " + r + " in app " + r.app);
10529 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
10530 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010531 long now = SystemClock.uptimeMillis();
10532 if (r.executeNesting == 0 && r.app != null) {
10533 if (r.app.executingServices.size() == 0) {
10534 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10535 msg.obj = r.app;
10536 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10537 }
10538 r.app.executingServices.add(r);
10539 }
10540 r.executeNesting++;
10541 r.executingStart = now;
10542 }
10543
10544 private final void sendServiceArgsLocked(ServiceRecord r,
10545 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010546 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010547 if (N == 0) {
10548 return;
10549 }
10550
Dianne Hackborn39792d22010-08-19 18:01:52 -070010551 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010552 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010553 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010554 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10555 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010556 if (si.intent == null && N > 1) {
10557 // If somehow we got a dummy null intent in the middle,
10558 // then skip it. DO NOT skip a null intent when it is
10559 // the only one in the list -- this is to support the
10560 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010561 continue;
10562 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010563 si.deliveredTime = SystemClock.uptimeMillis();
10564 r.deliveredStarts.add(si);
10565 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010566 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010567 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010568 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010569 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010570 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010571 if (!oomAdjusted) {
10572 oomAdjusted = true;
10573 updateOomAdjLocked(r.app);
10574 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010575 int flags = 0;
10576 if (si.deliveryCount > 0) {
10577 flags |= Service.START_FLAG_RETRY;
10578 }
10579 if (si.doneExecutingCount > 0) {
10580 flags |= Service.START_FLAG_REDELIVERY;
10581 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010582 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010583 } catch (RemoteException e) {
10584 // Remote process gone... we'll let the normal cleanup take
10585 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010586 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010587 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010588 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010589 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010590 break;
10591 }
10592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010593 }
10594
10595 private final boolean requestServiceBindingLocked(ServiceRecord r,
10596 IntentBindRecord i, boolean rebind) {
10597 if (r.app == null || r.app.thread == null) {
10598 // If service is not currently running, can't yet bind.
10599 return false;
10600 }
10601 if ((!i.requested || rebind) && i.apps.size() > 0) {
10602 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010603 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010604 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10605 if (!rebind) {
10606 i.requested = true;
10607 }
10608 i.hasBound = true;
10609 i.doRebind = false;
10610 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010611 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010612 return false;
10613 }
10614 }
10615 return true;
10616 }
10617
10618 private final void requestServiceBindingsLocked(ServiceRecord r) {
10619 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10620 while (bindings.hasNext()) {
10621 IntentBindRecord i = bindings.next();
10622 if (!requestServiceBindingLocked(r, i, false)) {
10623 break;
10624 }
10625 }
10626 }
10627
10628 private final void realStartServiceLocked(ServiceRecord r,
10629 ProcessRecord app) throws RemoteException {
10630 if (app.thread == null) {
10631 throw new RemoteException();
10632 }
10633
10634 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010635 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010636
10637 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010638 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010639 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010640
10641 boolean created = false;
10642 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010643 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010644 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010645 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010646 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010647 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010648 synchronized (r.stats.getBatteryStats()) {
10649 r.stats.startLaunchedLocked();
10650 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010651 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010652 app.thread.scheduleCreateService(r, r.serviceInfo,
10653 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010654 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010655 created = true;
10656 } finally {
10657 if (!created) {
10658 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010659 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010660 }
10661 }
10662
10663 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010664
10665 // If the service is in the started state, and there are no
10666 // pending arguments, then fake up one so its onStartCommand() will
10667 // be called.
10668 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010669 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10670 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010671 }
10672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010673 sendServiceArgsLocked(r, true);
10674 }
10675
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010676 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10677 boolean allowCancel) {
10678 boolean canceled = false;
10679
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010680 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010681 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010682 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010683
Dianne Hackborn070783f2010-12-29 16:46:28 -080010684 if ((r.serviceInfo.applicationInfo.flags
10685 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10686 minDuration /= 4;
10687 }
10688
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010689 // Any delivered but not yet finished starts should be put back
10690 // on the pending list.
10691 final int N = r.deliveredStarts.size();
10692 if (N > 0) {
10693 for (int i=N-1; i>=0; i--) {
10694 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010695 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010696 if (si.intent == null) {
10697 // We'll generate this again if needed.
10698 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10699 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10700 r.pendingStarts.add(0, si);
10701 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10702 dur *= 2;
10703 if (minDuration < dur) minDuration = dur;
10704 if (resetTime < dur) resetTime = dur;
10705 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010706 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010707 + r.name);
10708 canceled = true;
10709 }
10710 }
10711 r.deliveredStarts.clear();
10712 }
10713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010714 r.totalRestartCount++;
10715 if (r.restartDelay == 0) {
10716 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010717 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010718 } else {
10719 // If it has been a "reasonably long time" since the service
10720 // was started, then reset our restart duration back to
10721 // the beginning, so we don't infinitely increase the duration
10722 // on a service that just occasionally gets killed (which is
10723 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010724 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010725 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010726 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010727 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010728 if ((r.serviceInfo.applicationInfo.flags
10729 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10730 // Services in peristent processes will restart much more
10731 // quickly, since they are pretty important. (Think SystemUI).
10732 r.restartDelay += minDuration/2;
10733 } else {
10734 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10735 if (r.restartDelay < minDuration) {
10736 r.restartDelay = minDuration;
10737 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010738 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010739 }
10740 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010741
10742 r.nextRestartTime = now + r.restartDelay;
10743
10744 // Make sure that we don't end up restarting a bunch of services
10745 // all at the same time.
10746 boolean repeat;
10747 do {
10748 repeat = false;
10749 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10750 ServiceRecord r2 = mRestartingServices.get(i);
10751 if (r2 != r && r.nextRestartTime
10752 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10753 && r.nextRestartTime
10754 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10755 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10756 r.restartDelay = r.nextRestartTime - now;
10757 repeat = true;
10758 break;
10759 }
10760 }
10761 } while (repeat);
10762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010763 if (!mRestartingServices.contains(r)) {
10764 mRestartingServices.add(r);
10765 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010766
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010767 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010769 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010770 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010771 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010772 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010773 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010774 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010775 r.shortName, r.restartDelay);
10776
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010777 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010778 }
10779
10780 final void performServiceRestartLocked(ServiceRecord r) {
10781 if (!mRestartingServices.contains(r)) {
10782 return;
10783 }
10784 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10785 }
10786
10787 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10788 if (r.restartDelay == 0) {
10789 return false;
10790 }
10791 r.resetRestartCounter();
10792 mRestartingServices.remove(r);
10793 mHandler.removeCallbacks(r.restarter);
10794 return true;
10795 }
10796
10797 private final boolean bringUpServiceLocked(ServiceRecord r,
10798 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010799 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010800 //r.dump(" ");
10801
Dianne Hackborn36124872009-10-08 16:22:03 -070010802 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010803 sendServiceArgsLocked(r, false);
10804 return true;
10805 }
10806
10807 if (!whileRestarting && r.restartDelay > 0) {
10808 // If waiting for a restart, then do nothing.
10809 return true;
10810 }
10811
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010812 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010813
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010814 // We are now bringing the service up, so no longer in the
10815 // restarting state.
10816 mRestartingServices.remove(r);
10817
Dianne Hackborne7f97212011-02-24 14:40:20 -080010818 // Service is now being launched, its package can't be stopped.
10819 try {
10820 AppGlobals.getPackageManager().setPackageStoppedState(
10821 r.packageName, false);
10822 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010823 } catch (IllegalArgumentException e) {
10824 Slog.w(TAG, "Failed trying to unstop package "
10825 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010826 }
10827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010828 final String appName = r.processName;
10829 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10830 if (app != null && app.thread != null) {
10831 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010832 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010833 realStartServiceLocked(r, app);
10834 return true;
10835 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010836 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010837 }
10838
10839 // If a dead object exception was thrown -- fall through to
10840 // restart the application.
10841 }
10842
Dianne Hackborn36124872009-10-08 16:22:03 -070010843 // Not running -- get it started, and enqueue this service record
10844 // to be executed when the app comes up.
10845 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10846 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010847 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010848 + r.appInfo.packageName + "/"
10849 + r.appInfo.uid + " for service "
10850 + r.intent.getIntent() + ": process is bad");
10851 bringDownServiceLocked(r, true);
10852 return false;
10853 }
10854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010855 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010856 mPendingServices.add(r);
10857 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010858
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010859 return true;
10860 }
10861
10862 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010863 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010864 //r.dump(" ");
10865
10866 // Does it still need to run?
10867 if (!force && r.startRequested) {
10868 return;
10869 }
10870 if (r.connections.size() > 0) {
10871 if (!force) {
10872 // XXX should probably keep a count of the number of auto-create
10873 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010874 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010875 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010876 ArrayList<ConnectionRecord> cr = it.next();
10877 for (int i=0; i<cr.size(); i++) {
10878 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10879 return;
10880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010881 }
10882 }
10883 }
10884
10885 // Report to all of the connections that the service is no longer
10886 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010887 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010888 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010889 ArrayList<ConnectionRecord> c = it.next();
10890 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010891 ConnectionRecord cr = c.get(i);
10892 // There is still a connection to the service that is
10893 // being brought down. Mark it as dead.
10894 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010895 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010896 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010897 } catch (Exception e) {
10898 Slog.w(TAG, "Failure disconnecting service " + r.name +
10899 " to connection " + c.get(i).conn.asBinder() +
10900 " (in " + c.get(i).binding.client.processName + ")", e);
10901 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010902 }
10903 }
10904 }
10905
10906 // Tell the service that it has been unbound.
10907 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10908 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10909 while (it.hasNext()) {
10910 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010911 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010912 + ": hasBound=" + ibr.hasBound);
10913 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10914 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010915 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010916 updateOomAdjLocked(r.app);
10917 ibr.hasBound = false;
10918 r.app.thread.scheduleUnbindService(r,
10919 ibr.intent.getIntent());
10920 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010921 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010922 + r.shortName, e);
10923 serviceDoneExecutingLocked(r, true);
10924 }
10925 }
10926 }
10927 }
10928
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010929 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010930 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010931 System.identityHashCode(r), r.shortName,
10932 (r.app != null) ? r.app.pid : -1);
10933
10934 mServices.remove(r.name);
10935 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010936 r.totalRestartCount = 0;
10937 unscheduleServiceRestartLocked(r);
10938
10939 // Also make sure it is not on the pending list.
10940 int N = mPendingServices.size();
10941 for (int i=0; i<N; i++) {
10942 if (mPendingServices.get(i) == r) {
10943 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010944 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010945 i--;
10946 N--;
10947 }
10948 }
10949
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010950 r.cancelNotification();
10951 r.isForeground = false;
10952 r.foregroundId = 0;
10953 r.foregroundNoti = null;
10954
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010955 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010956 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010957 r.pendingStarts.clear();
10958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010959 if (r.app != null) {
10960 synchronized (r.stats.getBatteryStats()) {
10961 r.stats.stopLaunchedLocked();
10962 }
10963 r.app.services.remove(r);
10964 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010965 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010966 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010967 mStoppingServices.add(r);
10968 updateOomAdjLocked(r.app);
10969 r.app.thread.scheduleStopService(r);
10970 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010971 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010972 + r.shortName, e);
10973 serviceDoneExecutingLocked(r, true);
10974 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010975 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010976 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010977 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010978 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010979 }
10980 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010981 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010982 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010983 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010984
10985 if (r.bindings.size() > 0) {
10986 r.bindings.clear();
10987 }
10988
10989 if (r.restarter instanceof ServiceRestarter) {
10990 ((ServiceRestarter)r.restarter).setService(null);
10991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010992 }
10993
10994 ComponentName startServiceLocked(IApplicationThread caller,
10995 Intent service, String resolvedType,
10996 int callingPid, int callingUid) {
10997 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010998 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010999 + " type=" + resolvedType + " args=" + service.getExtras());
11000
11001 if (caller != null) {
11002 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11003 if (callerApp == null) {
11004 throw new SecurityException(
11005 "Unable to find app for caller " + caller
11006 + " (pid=" + Binder.getCallingPid()
11007 + ") when starting service " + service);
11008 }
11009 }
11010
11011 ServiceLookupResult res =
11012 retrieveServiceLocked(service, resolvedType,
11013 callingPid, callingUid);
11014 if (res == null) {
11015 return null;
11016 }
11017 if (res.record == null) {
11018 return new ComponentName("!", res.permission != null
11019 ? res.permission : "private to package");
11020 }
11021 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070011022 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
11023 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011025 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011026 }
11027 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011028 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011029 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070011030 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011031 r.lastActivity = SystemClock.uptimeMillis();
11032 synchronized (r.stats.getBatteryStats()) {
11033 r.stats.startRunningLocked();
11034 }
11035 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11036 return new ComponentName("!", "Service process is bad");
11037 }
11038 return r.name;
11039 }
11040 }
11041
11042 public ComponentName startService(IApplicationThread caller, Intent service,
11043 String resolvedType) {
11044 // Refuse possible leaked file descriptors
11045 if (service != null && service.hasFileDescriptors() == true) {
11046 throw new IllegalArgumentException("File descriptors passed in Intent");
11047 }
11048
11049 synchronized(this) {
11050 final int callingPid = Binder.getCallingPid();
11051 final int callingUid = Binder.getCallingUid();
11052 final long origId = Binder.clearCallingIdentity();
11053 ComponentName res = startServiceLocked(caller, service,
11054 resolvedType, callingPid, callingUid);
11055 Binder.restoreCallingIdentity(origId);
11056 return res;
11057 }
11058 }
11059
11060 ComponentName startServiceInPackage(int uid,
11061 Intent service, String resolvedType) {
11062 synchronized(this) {
11063 final long origId = Binder.clearCallingIdentity();
11064 ComponentName res = startServiceLocked(null, service,
11065 resolvedType, -1, uid);
11066 Binder.restoreCallingIdentity(origId);
11067 return res;
11068 }
11069 }
11070
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011071 private void stopServiceLocked(ServiceRecord service) {
11072 synchronized (service.stats.getBatteryStats()) {
11073 service.stats.stopRunningLocked();
11074 }
11075 service.startRequested = false;
11076 service.callStart = false;
11077 bringDownServiceLocked(service, false);
11078 }
11079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011080 public int stopService(IApplicationThread caller, Intent service,
11081 String resolvedType) {
11082 // Refuse possible leaked file descriptors
11083 if (service != null && service.hasFileDescriptors() == true) {
11084 throw new IllegalArgumentException("File descriptors passed in Intent");
11085 }
11086
11087 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011088 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011089 + " type=" + resolvedType);
11090
11091 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11092 if (caller != null && callerApp == null) {
11093 throw new SecurityException(
11094 "Unable to find app for caller " + caller
11095 + " (pid=" + Binder.getCallingPid()
11096 + ") when stopping service " + service);
11097 }
11098
11099 // If this service is active, make sure it is stopped.
11100 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11101 if (r != null) {
11102 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011103 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011104 try {
11105 stopServiceLocked(r.record);
11106 } finally {
11107 Binder.restoreCallingIdentity(origId);
11108 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011109 return 1;
11110 }
11111 return -1;
11112 }
11113 }
11114
11115 return 0;
11116 }
11117
11118 public IBinder peekService(Intent service, String resolvedType) {
11119 // Refuse possible leaked file descriptors
11120 if (service != null && service.hasFileDescriptors() == true) {
11121 throw new IllegalArgumentException("File descriptors passed in Intent");
11122 }
11123
11124 IBinder ret = null;
11125
11126 synchronized(this) {
11127 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11128
11129 if (r != null) {
11130 // r.record is null if findServiceLocked() failed the caller permission check
11131 if (r.record == null) {
11132 throw new SecurityException(
11133 "Permission Denial: Accessing service " + r.record.name
11134 + " from pid=" + Binder.getCallingPid()
11135 + ", uid=" + Binder.getCallingUid()
11136 + " requires " + r.permission);
11137 }
11138 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11139 if (ib != null) {
11140 ret = ib.binder;
11141 }
11142 }
11143 }
11144
11145 return ret;
11146 }
11147
11148 public boolean stopServiceToken(ComponentName className, IBinder token,
11149 int startId) {
11150 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011151 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011152 + " " + token + " startId=" + startId);
11153 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011154 if (r != null) {
11155 if (startId >= 0) {
11156 // Asked to only stop if done with all work. Note that
11157 // to avoid leaks, we will take this as dropping all
11158 // start items up to and including this one.
11159 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11160 if (si != null) {
11161 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011162 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11163 cur.removeUriPermissionsLocked();
11164 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011165 break;
11166 }
11167 }
11168 }
11169
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011170 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011171 return false;
11172 }
11173
11174 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011175 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011176 + " is last, but have " + r.deliveredStarts.size()
11177 + " remaining args");
11178 }
11179 }
11180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011181 synchronized (r.stats.getBatteryStats()) {
11182 r.stats.stopRunningLocked();
11183 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011184 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011185 }
11186 final long origId = Binder.clearCallingIdentity();
11187 bringDownServiceLocked(r, false);
11188 Binder.restoreCallingIdentity(origId);
11189 return true;
11190 }
11191 }
11192 return false;
11193 }
11194
11195 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011196 int id, Notification notification, boolean removeNotification) {
11197 final long origId = Binder.clearCallingIdentity();
11198 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011199 synchronized(this) {
11200 ServiceRecord r = findServiceLocked(className, token);
11201 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011202 if (id != 0) {
11203 if (notification == null) {
11204 throw new IllegalArgumentException("null notification");
11205 }
11206 if (r.foregroundId != id) {
11207 r.cancelNotification();
11208 r.foregroundId = id;
11209 }
11210 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11211 r.foregroundNoti = notification;
11212 r.isForeground = true;
11213 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011214 if (r.app != null) {
11215 updateServiceForegroundLocked(r.app, true);
11216 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011217 } else {
11218 if (r.isForeground) {
11219 r.isForeground = false;
11220 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070011221 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011222 updateServiceForegroundLocked(r.app, true);
11223 }
11224 }
11225 if (removeNotification) {
11226 r.cancelNotification();
11227 r.foregroundId = 0;
11228 r.foregroundNoti = null;
11229 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011230 }
11231 }
11232 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011233 } finally {
11234 Binder.restoreCallingIdentity(origId);
11235 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011236 }
11237
11238 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11239 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070011240 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011241 if (sr.isForeground) {
11242 anyForeground = true;
11243 break;
11244 }
11245 }
11246 if (anyForeground != proc.foregroundServices) {
11247 proc.foregroundServices = anyForeground;
11248 if (oomAdj) {
11249 updateOomAdjLocked();
11250 }
11251 }
11252 }
11253
11254 public int bindService(IApplicationThread caller, IBinder token,
11255 Intent service, String resolvedType,
11256 IServiceConnection connection, int flags) {
11257 // Refuse possible leaked file descriptors
11258 if (service != null && service.hasFileDescriptors() == true) {
11259 throw new IllegalArgumentException("File descriptors passed in Intent");
11260 }
11261
11262 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011263 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011264 + " type=" + resolvedType + " conn=" + connection.asBinder()
11265 + " flags=0x" + Integer.toHexString(flags));
11266 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11267 if (callerApp == null) {
11268 throw new SecurityException(
11269 "Unable to find app for caller " + caller
11270 + " (pid=" + Binder.getCallingPid()
11271 + ") when binding service " + service);
11272 }
11273
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011274 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011275 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011276 activity = mMainStack.isInStackLocked(token);
11277 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011278 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011279 return 0;
11280 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011281 }
11282
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011283 int clientLabel = 0;
11284 PendingIntent clientIntent = null;
11285
11286 if (callerApp.info.uid == Process.SYSTEM_UID) {
11287 // Hacky kind of thing -- allow system stuff to tell us
11288 // what they are, so we can report this elsewhere for
11289 // others to know why certain services are running.
11290 try {
11291 clientIntent = (PendingIntent)service.getParcelableExtra(
11292 Intent.EXTRA_CLIENT_INTENT);
11293 } catch (RuntimeException e) {
11294 }
11295 if (clientIntent != null) {
11296 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11297 if (clientLabel != 0) {
11298 // There are no useful extras in the intent, trash them.
11299 // System code calling with this stuff just needs to know
11300 // this will happen.
11301 service = service.cloneFilter();
11302 }
11303 }
11304 }
11305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011306 ServiceLookupResult res =
11307 retrieveServiceLocked(service, resolvedType,
11308 Binder.getCallingPid(), Binder.getCallingUid());
11309 if (res == null) {
11310 return 0;
11311 }
11312 if (res.record == null) {
11313 return -1;
11314 }
11315 ServiceRecord s = res.record;
11316
11317 final long origId = Binder.clearCallingIdentity();
11318
11319 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011320 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011321 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011322 }
11323
11324 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11325 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011326 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011327
11328 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011329 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11330 if (clist == null) {
11331 clist = new ArrayList<ConnectionRecord>();
11332 s.connections.put(binder, clist);
11333 }
11334 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011335 b.connections.add(c);
11336 if (activity != null) {
11337 if (activity.connections == null) {
11338 activity.connections = new HashSet<ConnectionRecord>();
11339 }
11340 activity.connections.add(c);
11341 }
11342 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011343 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11344 b.client.hasAboveClient = true;
11345 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011346 clist = mServiceConnections.get(binder);
11347 if (clist == null) {
11348 clist = new ArrayList<ConnectionRecord>();
11349 mServiceConnections.put(binder, clist);
11350 }
11351 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011352
11353 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11354 s.lastActivity = SystemClock.uptimeMillis();
11355 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11356 return 0;
11357 }
11358 }
11359
11360 if (s.app != null) {
11361 // This could have made the service more important.
11362 updateOomAdjLocked(s.app);
11363 }
11364
Joe Onorato8a9b2202010-02-26 18:56:32 -080011365 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011366 + ": received=" + b.intent.received
11367 + " apps=" + b.intent.apps.size()
11368 + " doRebind=" + b.intent.doRebind);
11369
11370 if (s.app != null && b.intent.received) {
11371 // Service is already running, so we can immediately
11372 // publish the connection.
11373 try {
11374 c.conn.connected(s.name, b.intent.binder);
11375 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011376 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011377 + " to connection " + c.conn.asBinder()
11378 + " (in " + c.binding.client.processName + ")", e);
11379 }
11380
11381 // If this is the first app connected back to this binding,
11382 // and the service had previously asked to be told when
11383 // rebound, then do so.
11384 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11385 requestServiceBindingLocked(s, b.intent, true);
11386 }
11387 } else if (!b.intent.requested) {
11388 requestServiceBindingLocked(s, b.intent, false);
11389 }
11390
11391 Binder.restoreCallingIdentity(origId);
11392 }
11393
11394 return 1;
11395 }
11396
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011397 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011398 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011399 IBinder binder = c.conn.asBinder();
11400 AppBindRecord b = c.binding;
11401 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011402 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11403 if (clist != null) {
11404 clist.remove(c);
11405 if (clist.size() == 0) {
11406 s.connections.remove(binder);
11407 }
11408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011409 b.connections.remove(c);
11410 if (c.activity != null && c.activity != skipAct) {
11411 if (c.activity.connections != null) {
11412 c.activity.connections.remove(c);
11413 }
11414 }
11415 if (b.client != skipApp) {
11416 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011417 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11418 b.client.updateHasAboveClientLocked();
11419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011420 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011421 clist = mServiceConnections.get(binder);
11422 if (clist != null) {
11423 clist.remove(c);
11424 if (clist.size() == 0) {
11425 mServiceConnections.remove(binder);
11426 }
11427 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011428
11429 if (b.connections.size() == 0) {
11430 b.intent.apps.remove(b.client);
11431 }
11432
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011433 if (!c.serviceDead) {
11434 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
11435 + ": shouldUnbind=" + b.intent.hasBound);
11436 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11437 && b.intent.hasBound) {
11438 try {
11439 bumpServiceExecutingLocked(s, "unbind");
11440 updateOomAdjLocked(s.app);
11441 b.intent.hasBound = false;
11442 // Assume the client doesn't want to know about a rebind;
11443 // we will deal with that later if it asks for one.
11444 b.intent.doRebind = false;
11445 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11446 } catch (Exception e) {
11447 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
11448 serviceDoneExecutingLocked(s, true);
11449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011450 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011451
11452 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11453 bringDownServiceLocked(s, false);
11454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011455 }
11456 }
11457
11458 public boolean unbindService(IServiceConnection connection) {
11459 synchronized (this) {
11460 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011461 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011462 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
11463 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011464 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011465 + connection.asBinder());
11466 return false;
11467 }
11468
11469 final long origId = Binder.clearCallingIdentity();
11470
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011471 while (clist.size() > 0) {
11472 ConnectionRecord r = clist.get(0);
11473 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011474
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011475 if (r.binding.service.app != null) {
11476 // This could have made the service less important.
11477 updateOomAdjLocked(r.binding.service.app);
11478 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011479 }
11480
11481 Binder.restoreCallingIdentity(origId);
11482 }
11483
11484 return true;
11485 }
11486
11487 public void publishService(IBinder token, Intent intent, IBinder service) {
11488 // Refuse possible leaked file descriptors
11489 if (intent != null && intent.hasFileDescriptors() == true) {
11490 throw new IllegalArgumentException("File descriptors passed in Intent");
11491 }
11492
11493 synchronized(this) {
11494 if (!(token instanceof ServiceRecord)) {
11495 throw new IllegalArgumentException("Invalid service token");
11496 }
11497 ServiceRecord r = (ServiceRecord)token;
11498
11499 final long origId = Binder.clearCallingIdentity();
11500
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011501 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011502 + " " + intent + ": " + service);
11503 if (r != null) {
11504 Intent.FilterComparison filter
11505 = new Intent.FilterComparison(intent);
11506 IntentBindRecord b = r.bindings.get(filter);
11507 if (b != null && !b.received) {
11508 b.binder = service;
11509 b.requested = true;
11510 b.received = true;
11511 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011512 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011513 = r.connections.values().iterator();
11514 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011515 ArrayList<ConnectionRecord> clist = it.next();
11516 for (int i=0; i<clist.size(); i++) {
11517 ConnectionRecord c = clist.get(i);
11518 if (!filter.equals(c.binding.intent.intent)) {
11519 if (DEBUG_SERVICE) Slog.v(
11520 TAG, "Not publishing to: " + c);
11521 if (DEBUG_SERVICE) Slog.v(
11522 TAG, "Bound intent: " + c.binding.intent.intent);
11523 if (DEBUG_SERVICE) Slog.v(
11524 TAG, "Published intent: " + intent);
11525 continue;
11526 }
11527 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
11528 try {
11529 c.conn.connected(r.name, service);
11530 } catch (Exception e) {
11531 Slog.w(TAG, "Failure sending service " + r.name +
11532 " to connection " + c.conn.asBinder() +
11533 " (in " + c.binding.client.processName + ")", e);
11534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011535 }
11536 }
11537 }
11538 }
11539
11540 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11541
11542 Binder.restoreCallingIdentity(origId);
11543 }
11544 }
11545 }
11546
11547 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11548 // Refuse possible leaked file descriptors
11549 if (intent != null && intent.hasFileDescriptors() == true) {
11550 throw new IllegalArgumentException("File descriptors passed in Intent");
11551 }
11552
11553 synchronized(this) {
11554 if (!(token instanceof ServiceRecord)) {
11555 throw new IllegalArgumentException("Invalid service token");
11556 }
11557 ServiceRecord r = (ServiceRecord)token;
11558
11559 final long origId = Binder.clearCallingIdentity();
11560
11561 if (r != null) {
11562 Intent.FilterComparison filter
11563 = new Intent.FilterComparison(intent);
11564 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011565 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011566 + " at " + b + ": apps="
11567 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011568
11569 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011570 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011571 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011572 // Applications have already bound since the last
11573 // unbind, so just rebind right here.
11574 requestServiceBindingLocked(r, b, true);
11575 } else {
11576 // Note to tell the service the next time there is
11577 // a new client.
11578 b.doRebind = true;
11579 }
11580 }
11581
Per Edelberg78f9fff2010-08-30 20:01:35 +020011582 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011583
11584 Binder.restoreCallingIdentity(origId);
11585 }
11586 }
11587 }
11588
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011589 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011590 synchronized(this) {
11591 if (!(token instanceof ServiceRecord)) {
11592 throw new IllegalArgumentException("Invalid service token");
11593 }
11594 ServiceRecord r = (ServiceRecord)token;
11595 boolean inStopping = mStoppingServices.contains(token);
11596 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011597 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011598 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011599 + " with incorrect token: given " + token
11600 + ", expected " + r);
11601 return;
11602 }
11603
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011604 if (type == 1) {
11605 // This is a call from a service start... take care of
11606 // book-keeping.
11607 r.callStart = true;
11608 switch (res) {
11609 case Service.START_STICKY_COMPATIBILITY:
11610 case Service.START_STICKY: {
11611 // We are done with the associated start arguments.
11612 r.findDeliveredStart(startId, true);
11613 // Don't stop if killed.
11614 r.stopIfKilled = false;
11615 break;
11616 }
11617 case Service.START_NOT_STICKY: {
11618 // We are done with the associated start arguments.
11619 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011620 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011621 // There is no more work, and this service
11622 // doesn't want to hang around if killed.
11623 r.stopIfKilled = true;
11624 }
11625 break;
11626 }
11627 case Service.START_REDELIVER_INTENT: {
11628 // We'll keep this item until they explicitly
11629 // call stop for it, but keep track of the fact
11630 // that it was delivered.
11631 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11632 if (si != null) {
11633 si.deliveryCount = 0;
11634 si.doneExecutingCount++;
11635 // Don't stop if killed.
11636 r.stopIfKilled = true;
11637 }
11638 break;
11639 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011640 case Service.START_TASK_REMOVED_COMPLETE: {
11641 // Special processing for onTaskRemoved(). Don't
11642 // impact normal onStartCommand() processing.
11643 r.findDeliveredStart(startId, true);
11644 break;
11645 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011646 default:
11647 throw new IllegalArgumentException(
11648 "Unknown service start result: " + res);
11649 }
11650 if (res == Service.START_STICKY_COMPATIBILITY) {
11651 r.callStart = false;
11652 }
11653 }
11654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011655 final long origId = Binder.clearCallingIdentity();
11656 serviceDoneExecutingLocked(r, inStopping);
11657 Binder.restoreCallingIdentity(origId);
11658 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011659 Slog.w(TAG, "Done executing unknown service from pid "
11660 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011661 }
11662 }
11663 }
11664
11665 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011666 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11667 + ": nesting=" + r.executeNesting
11668 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011669 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011670 r.executeNesting--;
11671 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011672 if (DEBUG_SERVICE) Slog.v(TAG,
11673 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011674 r.app.executingServices.remove(r);
11675 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011676 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11677 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011678 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11679 }
11680 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011681 if (DEBUG_SERVICE) Slog.v(TAG,
11682 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011683 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011684 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011685 }
11686 updateOomAdjLocked(r.app);
11687 }
11688 }
11689
11690 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011691 String anrMessage = null;
11692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011693 synchronized(this) {
11694 if (proc.executingServices.size() == 0 || proc.thread == null) {
11695 return;
11696 }
11697 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11698 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11699 ServiceRecord timeout = null;
11700 long nextTime = 0;
11701 while (it.hasNext()) {
11702 ServiceRecord sr = it.next();
11703 if (sr.executingStart < maxTime) {
11704 timeout = sr;
11705 break;
11706 }
11707 if (sr.executingStart > nextTime) {
11708 nextTime = sr.executingStart;
11709 }
11710 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011711 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011712 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011713 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011714 } else {
11715 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11716 msg.obj = proc;
11717 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11718 }
11719 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011720
11721 if (anrMessage != null) {
11722 appNotResponding(proc, null, null, anrMessage);
11723 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011724 }
11725
11726 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011727 // BACKUP AND RESTORE
11728 // =========================================================
11729
11730 // Cause the target app to be launched if necessary and its backup agent
11731 // instantiated. The backup agent will invoke backupAgentCreated() on the
11732 // activity manager to announce its creation.
11733 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011734 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011735 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11736
11737 synchronized(this) {
11738 // !!! TODO: currently no check here that we're already bound
11739 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11740 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11741 synchronized (stats) {
11742 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11743 }
11744
Dianne Hackborne7f97212011-02-24 14:40:20 -080011745 // Backup agent is now in use, its package can't be stopped.
11746 try {
11747 AppGlobals.getPackageManager().setPackageStoppedState(
11748 app.packageName, false);
11749 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011750 } catch (IllegalArgumentException e) {
11751 Slog.w(TAG, "Failed trying to unstop package "
11752 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011753 }
11754
Christopher Tate181fafa2009-05-14 11:12:14 -070011755 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011756 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11757 ? new ComponentName(app.packageName, app.backupAgentName)
11758 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011759 // startProcessLocked() returns existing proc's record if it's already running
11760 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011761 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011762 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011763 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011764 return false;
11765 }
11766
11767 r.app = proc;
11768 mBackupTarget = r;
11769 mBackupAppName = app.packageName;
11770
Christopher Tate6fa95972009-06-05 18:43:55 -070011771 // Try not to kill the process during backup
11772 updateOomAdjLocked(proc);
11773
Christopher Tate181fafa2009-05-14 11:12:14 -070011774 // If the process is already attached, schedule the creation of the backup agent now.
11775 // If it is not yet live, this will be done when it attaches to the framework.
11776 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011777 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011778 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011779 proc.thread.scheduleCreateBackupAgent(app,
11780 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011781 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011782 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011783 }
11784 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011785 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011786 }
11787 // Invariants: at this point, the target app process exists and the application
11788 // is either already running or in the process of coming up. mBackupTarget and
11789 // mBackupAppName describe the app, so that when it binds back to the AM we
11790 // know that it's scheduled for a backup-agent operation.
11791 }
11792
11793 return true;
11794 }
11795
11796 // A backup agent has just come up
11797 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011798 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011799 + " = " + agent);
11800
11801 synchronized(this) {
11802 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011803 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011804 return;
11805 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011806 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011807
Dianne Hackborn06740692010-09-22 22:46:21 -070011808 long oldIdent = Binder.clearCallingIdentity();
11809 try {
11810 IBackupManager bm = IBackupManager.Stub.asInterface(
11811 ServiceManager.getService(Context.BACKUP_SERVICE));
11812 bm.agentConnected(agentPackageName, agent);
11813 } catch (RemoteException e) {
11814 // can't happen; the backup manager service is local
11815 } catch (Exception e) {
11816 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11817 e.printStackTrace();
11818 } finally {
11819 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011820 }
11821 }
11822
11823 // done with this agent
11824 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011825 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011826 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011827 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011828 return;
11829 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011830
11831 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011832 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011833 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011834 return;
11835 }
11836
Christopher Tate181fafa2009-05-14 11:12:14 -070011837 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011838 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011839 return;
11840 }
11841
Christopher Tate6fa95972009-06-05 18:43:55 -070011842 ProcessRecord proc = mBackupTarget.app;
11843 mBackupTarget = null;
11844 mBackupAppName = null;
11845
11846 // Not backing this app up any more; reset its OOM adjustment
11847 updateOomAdjLocked(proc);
11848
Christopher Tatec7b31e32009-06-10 15:49:30 -070011849 // If the app crashed during backup, 'thread' will be null here
11850 if (proc.thread != null) {
11851 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011852 proc.thread.scheduleDestroyBackupAgent(appInfo,
11853 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011854 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011855 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011856 e.printStackTrace();
11857 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011858 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011859 }
11860 }
11861 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011862 // BROADCASTS
11863 // =========================================================
11864
Josh Bartel7f208742010-02-25 11:01:44 -060011865 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011866 List cur) {
11867 final ContentResolver resolver = mContext.getContentResolver();
11868 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11869 if (list == null) {
11870 return cur;
11871 }
11872 int N = list.size();
11873 for (int i=0; i<N; i++) {
11874 Intent intent = list.get(i);
11875 if (filter.match(resolver, intent, true, TAG) >= 0) {
11876 if (cur == null) {
11877 cur = new ArrayList<Intent>();
11878 }
11879 cur.add(intent);
11880 }
11881 }
11882 return cur;
11883 }
11884
11885 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011886 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011887 + mBroadcastsScheduled);
11888
11889 if (mBroadcastsScheduled) {
11890 return;
11891 }
11892 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11893 mBroadcastsScheduled = true;
11894 }
11895
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011896 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011897 IIntentReceiver receiver, IntentFilter filter, String permission) {
11898 synchronized(this) {
11899 ProcessRecord callerApp = null;
11900 if (caller != null) {
11901 callerApp = getRecordForAppLocked(caller);
11902 if (callerApp == null) {
11903 throw new SecurityException(
11904 "Unable to find app for caller " + caller
11905 + " (pid=" + Binder.getCallingPid()
11906 + ") when registering receiver " + receiver);
11907 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011908 if (callerApp.info.uid != Process.SYSTEM_UID &&
11909 !callerApp.pkgList.contains(callerPackage)) {
11910 throw new SecurityException("Given caller package " + callerPackage
11911 + " is not running in process " + callerApp);
11912 }
11913 } else {
11914 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011915 }
11916
11917 List allSticky = null;
11918
11919 // Look for any matching sticky broadcasts...
11920 Iterator actions = filter.actionsIterator();
11921 if (actions != null) {
11922 while (actions.hasNext()) {
11923 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011924 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011925 }
11926 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011927 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011928 }
11929
11930 // The first sticky in the list is returned directly back to
11931 // the client.
11932 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11933
Joe Onorato8a9b2202010-02-26 18:56:32 -080011934 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011935 + ": " + sticky);
11936
11937 if (receiver == null) {
11938 return sticky;
11939 }
11940
11941 ReceiverList rl
11942 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11943 if (rl == null) {
11944 rl = new ReceiverList(this, callerApp,
11945 Binder.getCallingPid(),
11946 Binder.getCallingUid(), receiver);
11947 if (rl.app != null) {
11948 rl.app.receivers.add(rl);
11949 } else {
11950 try {
11951 receiver.asBinder().linkToDeath(rl, 0);
11952 } catch (RemoteException e) {
11953 return sticky;
11954 }
11955 rl.linkedToDeath = true;
11956 }
11957 mRegisteredReceivers.put(receiver.asBinder(), rl);
11958 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011959 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011960 rl.add(bf);
11961 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011962 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011963 }
11964 mReceiverResolver.addFilter(bf);
11965
11966 // Enqueue broadcasts for all existing stickies that match
11967 // this filter.
11968 if (allSticky != null) {
11969 ArrayList receivers = new ArrayList();
11970 receivers.add(bf);
11971
11972 int N = allSticky.size();
11973 for (int i=0; i<N; i++) {
11974 Intent intent = (Intent)allSticky.get(i);
11975 BroadcastRecord r = new BroadcastRecord(intent, null,
11976 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011977 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011978 if (mParallelBroadcasts.size() == 0) {
11979 scheduleBroadcastsLocked();
11980 }
11981 mParallelBroadcasts.add(r);
11982 }
11983 }
11984
11985 return sticky;
11986 }
11987 }
11988
11989 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011990 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011991
11992 boolean doNext = false;
11993
11994 synchronized(this) {
11995 ReceiverList rl
11996 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11997 if (rl != null) {
11998 if (rl.curBroadcast != null) {
11999 BroadcastRecord r = rl.curBroadcast;
12000 doNext = finishReceiverLocked(
12001 receiver.asBinder(), r.resultCode, r.resultData,
12002 r.resultExtras, r.resultAbort, true);
12003 }
12004
12005 if (rl.app != null) {
12006 rl.app.receivers.remove(rl);
12007 }
12008 removeReceiverLocked(rl);
12009 if (rl.linkedToDeath) {
12010 rl.linkedToDeath = false;
12011 rl.receiver.asBinder().unlinkToDeath(rl, 0);
12012 }
12013 }
12014 }
12015
12016 if (!doNext) {
12017 return;
12018 }
12019
12020 final long origId = Binder.clearCallingIdentity();
12021 processNextBroadcast(false);
12022 trimApplications();
12023 Binder.restoreCallingIdentity(origId);
12024 }
12025
12026 void removeReceiverLocked(ReceiverList rl) {
12027 mRegisteredReceivers.remove(rl.receiver.asBinder());
12028 int N = rl.size();
12029 for (int i=0; i<N; i++) {
12030 mReceiverResolver.removeFilter(rl.get(i));
12031 }
12032 }
12033
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012034 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12035 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12036 ProcessRecord r = mLruProcesses.get(i);
12037 if (r.thread != null) {
12038 try {
12039 r.thread.dispatchPackageBroadcast(cmd, packages);
12040 } catch (RemoteException ex) {
12041 }
12042 }
12043 }
12044 }
12045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012046 private final int broadcastIntentLocked(ProcessRecord callerApp,
12047 String callerPackage, Intent intent, String resolvedType,
12048 IIntentReceiver resultTo, int resultCode, String resultData,
12049 Bundle map, String requiredPermission,
12050 boolean ordered, boolean sticky, int callingPid, int callingUid) {
12051 intent = new Intent(intent);
12052
Dianne Hackborne7f97212011-02-24 14:40:20 -080012053 // By default broadcasts do not go to stopped apps.
12054 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12055
Joe Onorato8a9b2202010-02-26 18:56:32 -080012056 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012057 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
12058 + " ordered=" + ordered);
12059 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012060 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012061 }
12062
12063 // Handle special intents: if this broadcast is from the package
12064 // manager about a package being removed, we need to remove all of
12065 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012066 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012067 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012068 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12069 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012070 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012071 || uidRemoved) {
12072 if (checkComponentPermission(
12073 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012074 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012075 == PackageManager.PERMISSION_GRANTED) {
12076 if (uidRemoved) {
12077 final Bundle intentExtras = intent.getExtras();
12078 final int uid = intentExtras != null
12079 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12080 if (uid >= 0) {
12081 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12082 synchronized (bs) {
12083 bs.removeUidStatsLocked(uid);
12084 }
12085 }
12086 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012087 // If resources are unvailble just force stop all
12088 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012089 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012090 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12091 if (list != null && (list.length > 0)) {
12092 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070012093 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012094 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012095 sendPackageBroadcastLocked(
12096 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012097 }
12098 } else {
12099 Uri data = intent.getData();
12100 String ssp;
12101 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12102 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12103 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070012104 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070012105 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012106 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012107 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12108 new String[] {ssp});
12109 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012110 }
12111 }
12112 }
12113 } else {
12114 String msg = "Permission Denial: " + intent.getAction()
12115 + " broadcast from " + callerPackage + " (pid=" + callingPid
12116 + ", uid=" + callingUid + ")"
12117 + " requires "
12118 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012119 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012120 throw new SecurityException(msg);
12121 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012122
12123 // Special case for adding a package: by default turn on compatibility
12124 // mode.
12125 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070012126 Uri data = intent.getData();
12127 String ssp;
12128 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12129 mCompatModePackages.handlePackageAddedLocked(ssp,
12130 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012131 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012132 }
12133
12134 /*
12135 * If this is the time zone changed action, queue up a message that will reset the timezone
12136 * of all currently running processes. This message will get queued up before the broadcast
12137 * happens.
12138 */
12139 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12140 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12141 }
12142
Robert Greenwalt03595d02010-11-02 14:08:23 -070012143 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12144 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12145 }
12146
Robert Greenwalt434203a2010-10-11 16:00:27 -070012147 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12148 ProxyProperties proxy = intent.getParcelableExtra("proxy");
12149 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12150 }
12151
Dianne Hackborn854060af2009-07-09 18:14:31 -070012152 /*
12153 * Prevent non-system code (defined here to be non-persistent
12154 * processes) from sending protected broadcasts.
12155 */
12156 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12157 || callingUid == Process.SHELL_UID || callingUid == 0) {
12158 // Always okay.
12159 } else if (callerApp == null || !callerApp.persistent) {
12160 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012161 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070012162 intent.getAction())) {
12163 String msg = "Permission Denial: not allowed to send broadcast "
12164 + intent.getAction() + " from pid="
12165 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012166 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012167 throw new SecurityException(msg);
12168 }
12169 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012170 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012171 return BROADCAST_SUCCESS;
12172 }
12173 }
12174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012175 // Add to the sticky list if requested.
12176 if (sticky) {
12177 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12178 callingPid, callingUid)
12179 != PackageManager.PERMISSION_GRANTED) {
12180 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12181 + callingPid + ", uid=" + callingUid
12182 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012183 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012184 throw new SecurityException(msg);
12185 }
12186 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012187 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012188 + " and enforce permission " + requiredPermission);
12189 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12190 }
12191 if (intent.getComponent() != null) {
12192 throw new SecurityException(
12193 "Sticky broadcasts can't target a specific component");
12194 }
12195 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12196 if (list == null) {
12197 list = new ArrayList<Intent>();
12198 mStickyBroadcasts.put(intent.getAction(), list);
12199 }
12200 int N = list.size();
12201 int i;
12202 for (i=0; i<N; i++) {
12203 if (intent.filterEquals(list.get(i))) {
12204 // This sticky already exists, replace it.
12205 list.set(i, new Intent(intent));
12206 break;
12207 }
12208 }
12209 if (i >= N) {
12210 list.add(new Intent(intent));
12211 }
12212 }
12213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012214 // Figure out who all will receive this broadcast.
12215 List receivers = null;
12216 List<BroadcastFilter> registeredReceivers = null;
12217 try {
12218 if (intent.getComponent() != null) {
12219 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012220 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070012221 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012222 if (ai != null) {
12223 receivers = new ArrayList();
12224 ResolveInfo ri = new ResolveInfo();
12225 ri.activityInfo = ai;
12226 receivers.add(ri);
12227 }
12228 } else {
12229 // Need to resolve the intent to interested receivers...
12230 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12231 == 0) {
12232 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012233 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012234 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012235 }
Mihai Preda074edef2009-05-18 17:13:31 +020012236 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012237 }
12238 } catch (RemoteException ex) {
12239 // pm is in same process, this will never happen.
12240 }
12241
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012242 final boolean replacePending =
12243 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12244
Joe Onorato8a9b2202010-02-26 18:56:32 -080012245 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012246 + " replacePending=" + replacePending);
12247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012248 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12249 if (!ordered && NR > 0) {
12250 // If we are not serializing this broadcast, then send the
12251 // registered receivers separately so they don't wait for the
12252 // components to be launched.
12253 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12254 callerPackage, callingPid, callingUid, requiredPermission,
12255 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012256 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012257 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012258 TAG, "Enqueueing parallel broadcast " + r
12259 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012260 boolean replaced = false;
12261 if (replacePending) {
12262 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
12263 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012264 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012265 "***** DROPPING PARALLEL: " + intent);
12266 mParallelBroadcasts.set(i, r);
12267 replaced = true;
12268 break;
12269 }
12270 }
12271 }
12272 if (!replaced) {
12273 mParallelBroadcasts.add(r);
12274 scheduleBroadcastsLocked();
12275 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012276 registeredReceivers = null;
12277 NR = 0;
12278 }
12279
12280 // Merge into one list.
12281 int ir = 0;
12282 if (receivers != null) {
12283 // A special case for PACKAGE_ADDED: do not allow the package
12284 // being added to see this broadcast. This prevents them from
12285 // using this as a back door to get run as soon as they are
12286 // installed. Maybe in the future we want to have a special install
12287 // broadcast or such for apps, but we'd like to deliberately make
12288 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012289 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012290 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
12291 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
12292 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012293 Uri data = intent.getData();
12294 if (data != null) {
12295 String pkgName = data.getSchemeSpecificPart();
12296 if (pkgName != null) {
12297 skipPackages = new String[] { pkgName };
12298 }
12299 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012300 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012301 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070012302 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012303 if (skipPackages != null && (skipPackages.length > 0)) {
12304 for (String skipPackage : skipPackages) {
12305 if (skipPackage != null) {
12306 int NT = receivers.size();
12307 for (int it=0; it<NT; it++) {
12308 ResolveInfo curt = (ResolveInfo)receivers.get(it);
12309 if (curt.activityInfo.packageName.equals(skipPackage)) {
12310 receivers.remove(it);
12311 it--;
12312 NT--;
12313 }
12314 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012315 }
12316 }
12317 }
12318
12319 int NT = receivers != null ? receivers.size() : 0;
12320 int it = 0;
12321 ResolveInfo curt = null;
12322 BroadcastFilter curr = null;
12323 while (it < NT && ir < NR) {
12324 if (curt == null) {
12325 curt = (ResolveInfo)receivers.get(it);
12326 }
12327 if (curr == null) {
12328 curr = registeredReceivers.get(ir);
12329 }
12330 if (curr.getPriority() >= curt.priority) {
12331 // Insert this broadcast record into the final list.
12332 receivers.add(it, curr);
12333 ir++;
12334 curr = null;
12335 it++;
12336 NT++;
12337 } else {
12338 // Skip to the next ResolveInfo in the final list.
12339 it++;
12340 curt = null;
12341 }
12342 }
12343 }
12344 while (ir < NR) {
12345 if (receivers == null) {
12346 receivers = new ArrayList();
12347 }
12348 receivers.add(registeredReceivers.get(ir));
12349 ir++;
12350 }
12351
12352 if ((receivers != null && receivers.size() > 0)
12353 || resultTo != null) {
12354 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12355 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012356 receivers, resultTo, resultCode, resultData, map, ordered,
12357 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012358 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012359 TAG, "Enqueueing ordered broadcast " + r
12360 + ": prev had " + mOrderedBroadcasts.size());
12361 if (DEBUG_BROADCAST) {
12362 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012363 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012364 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012365 boolean replaced = false;
12366 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012367 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012368 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012369 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012370 "***** DROPPING ORDERED: " + intent);
12371 mOrderedBroadcasts.set(i, r);
12372 replaced = true;
12373 break;
12374 }
12375 }
12376 }
12377 if (!replaced) {
12378 mOrderedBroadcasts.add(r);
12379 scheduleBroadcastsLocked();
12380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012381 }
12382
12383 return BROADCAST_SUCCESS;
12384 }
12385
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012386 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012387 // Refuse possible leaked file descriptors
12388 if (intent != null && intent.hasFileDescriptors() == true) {
12389 throw new IllegalArgumentException("File descriptors passed in Intent");
12390 }
12391
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012392 int flags = intent.getFlags();
12393
12394 if (!mProcessesReady) {
12395 // if the caller really truly claims to know what they're doing, go
12396 // ahead and allow the broadcast without launching any receivers
12397 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12398 intent = new Intent(intent);
12399 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12400 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12401 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12402 + " before boot completion");
12403 throw new IllegalStateException("Cannot broadcast before boot completed");
12404 }
12405 }
12406
12407 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12408 throw new IllegalArgumentException(
12409 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12410 }
12411
12412 return intent;
12413 }
12414
12415 public final int broadcastIntent(IApplicationThread caller,
12416 Intent intent, String resolvedType, IIntentReceiver resultTo,
12417 int resultCode, String resultData, Bundle map,
12418 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012419 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012420 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012422 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12423 final int callingPid = Binder.getCallingPid();
12424 final int callingUid = Binder.getCallingUid();
12425 final long origId = Binder.clearCallingIdentity();
12426 int res = broadcastIntentLocked(callerApp,
12427 callerApp != null ? callerApp.info.packageName : null,
12428 intent, resolvedType, resultTo,
12429 resultCode, resultData, map, requiredPermission, serialized,
12430 sticky, callingPid, callingUid);
12431 Binder.restoreCallingIdentity(origId);
12432 return res;
12433 }
12434 }
12435
12436 int broadcastIntentInPackage(String packageName, int uid,
12437 Intent intent, String resolvedType, IIntentReceiver resultTo,
12438 int resultCode, String resultData, Bundle map,
12439 String requiredPermission, boolean serialized, boolean sticky) {
12440 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012441 intent = verifyBroadcastLocked(intent);
12442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012443 final long origId = Binder.clearCallingIdentity();
12444 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12445 resultTo, resultCode, resultData, map, requiredPermission,
12446 serialized, sticky, -1, uid);
12447 Binder.restoreCallingIdentity(origId);
12448 return res;
12449 }
12450 }
12451
12452 public final void unbroadcastIntent(IApplicationThread caller,
12453 Intent intent) {
12454 // Refuse possible leaked file descriptors
12455 if (intent != null && intent.hasFileDescriptors() == true) {
12456 throw new IllegalArgumentException("File descriptors passed in Intent");
12457 }
12458
12459 synchronized(this) {
12460 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12461 != PackageManager.PERMISSION_GRANTED) {
12462 String msg = "Permission Denial: unbroadcastIntent() from pid="
12463 + Binder.getCallingPid()
12464 + ", uid=" + Binder.getCallingUid()
12465 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012466 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012467 throw new SecurityException(msg);
12468 }
12469 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12470 if (list != null) {
12471 int N = list.size();
12472 int i;
12473 for (i=0; i<N; i++) {
12474 if (intent.filterEquals(list.get(i))) {
12475 list.remove(i);
12476 break;
12477 }
12478 }
12479 }
12480 }
12481 }
12482
12483 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12484 String resultData, Bundle resultExtras, boolean resultAbort,
12485 boolean explicit) {
12486 if (mOrderedBroadcasts.size() == 0) {
12487 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012488 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012489 }
12490 return false;
12491 }
12492 BroadcastRecord r = mOrderedBroadcasts.get(0);
12493 if (r.receiver == null) {
12494 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012495 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012496 }
12497 return false;
12498 }
12499 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012500 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012501 return false;
12502 }
12503 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012504 r.state = BroadcastRecord.IDLE;
12505 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012506 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012507 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012508 }
12509 }
12510 r.receiver = null;
12511 r.intent.setComponent(null);
12512 if (r.curApp != null) {
12513 r.curApp.curReceiver = null;
12514 }
12515 if (r.curFilter != null) {
12516 r.curFilter.receiverList.curBroadcast = null;
12517 }
12518 r.curFilter = null;
12519 r.curApp = null;
12520 r.curComponent = null;
12521 r.curReceiver = null;
12522 mPendingBroadcast = null;
12523
12524 r.resultCode = resultCode;
12525 r.resultData = resultData;
12526 r.resultExtras = resultExtras;
12527 r.resultAbort = resultAbort;
12528
12529 // We will process the next receiver right now if this is finishing
12530 // an app receiver (which is always asynchronous) or after we have
12531 // come back from calling a receiver.
12532 return state == BroadcastRecord.APP_RECEIVE
12533 || state == BroadcastRecord.CALL_DONE_RECEIVE;
12534 }
12535
12536 public void finishReceiver(IBinder who, int resultCode, String resultData,
12537 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012538 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012539
12540 // Refuse possible leaked file descriptors
12541 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12542 throw new IllegalArgumentException("File descriptors passed in Bundle");
12543 }
12544
12545 boolean doNext;
12546
12547 final long origId = Binder.clearCallingIdentity();
12548
12549 synchronized(this) {
12550 doNext = finishReceiverLocked(
12551 who, resultCode, resultData, resultExtras, resultAbort, true);
12552 }
12553
12554 if (doNext) {
12555 processNextBroadcast(false);
12556 }
12557 trimApplications();
12558
12559 Binder.restoreCallingIdentity(origId);
12560 }
12561
Jeff Brown4d94a762010-09-23 11:33:28 -070012562 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012563 if (r.nextReceiver > 0) {
12564 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12565 if (curReceiver instanceof BroadcastFilter) {
12566 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012567 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012568 System.identityHashCode(r),
12569 r.intent.getAction(),
12570 r.nextReceiver - 1,
12571 System.identityHashCode(bf));
12572 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012573 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012574 System.identityHashCode(r),
12575 r.intent.getAction(),
12576 r.nextReceiver - 1,
12577 ((ResolveInfo)curReceiver).toString());
12578 }
12579 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012580 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012581 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012582 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012583 System.identityHashCode(r),
12584 r.intent.getAction(),
12585 r.nextReceiver,
12586 "NONE");
12587 }
12588 }
12589
Jeff Brown4d94a762010-09-23 11:33:28 -070012590 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12591 if (! mPendingBroadcastTimeoutMessage) {
12592 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12593 mHandler.sendMessageAtTime(msg, timeoutTime);
12594 mPendingBroadcastTimeoutMessage = true;
12595 }
12596 }
12597
12598 private final void cancelBroadcastTimeoutLocked() {
12599 if (mPendingBroadcastTimeoutMessage) {
12600 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12601 mPendingBroadcastTimeoutMessage = false;
12602 }
12603 }
12604
12605 private final void broadcastTimeoutLocked(boolean fromMsg) {
12606 if (fromMsg) {
12607 mPendingBroadcastTimeoutMessage = false;
12608 }
12609
12610 if (mOrderedBroadcasts.size() == 0) {
12611 return;
12612 }
12613
12614 long now = SystemClock.uptimeMillis();
12615 BroadcastRecord r = mOrderedBroadcasts.get(0);
12616 if (fromMsg) {
12617 if (mDidDexOpt) {
12618 // Delay timeouts until dexopt finishes.
12619 mDidDexOpt = false;
12620 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12621 setBroadcastTimeoutLocked(timeoutTime);
12622 return;
12623 }
12624 if (! mProcessesReady) {
12625 // Only process broadcast timeouts if the system is ready. That way
12626 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12627 // to do heavy lifting for system up.
12628 return;
12629 }
12630
12631 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12632 if (timeoutTime > now) {
12633 // We can observe premature timeouts because we do not cancel and reset the
12634 // broadcast timeout message after each receiver finishes. Instead, we set up
12635 // an initial timeout then kick it down the road a little further as needed
12636 // when it expires.
12637 if (DEBUG_BROADCAST) Slog.v(TAG,
12638 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12639 + timeoutTime);
12640 setBroadcastTimeoutLocked(timeoutTime);
12641 return;
12642 }
12643 }
12644
12645 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12646 + ", started " + (now - r.receiverTime) + "ms ago");
12647 r.receiverTime = now;
12648 r.anrCount++;
12649
12650 // Current receiver has passed its expiration date.
12651 if (r.nextReceiver <= 0) {
12652 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12653 return;
12654 }
12655
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012656 ProcessRecord app = null;
12657 String anrMessage = null;
12658
Jeff Brown4d94a762010-09-23 11:33:28 -070012659 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12660 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12661 logBroadcastReceiverDiscardLocked(r);
12662 if (curReceiver instanceof BroadcastFilter) {
12663 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12664 if (bf.receiverList.pid != 0
12665 && bf.receiverList.pid != MY_PID) {
12666 synchronized (this.mPidsSelfLocked) {
12667 app = this.mPidsSelfLocked.get(
12668 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012669 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012670 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012671 } else {
12672 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012673 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012674
Jeff Brown4d94a762010-09-23 11:33:28 -070012675 if (app != null) {
12676 anrMessage = "Broadcast of " + r.intent.toString();
12677 }
12678
12679 if (mPendingBroadcast == r) {
12680 mPendingBroadcast = null;
12681 }
12682
12683 // Move on to the next receiver.
12684 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12685 r.resultExtras, r.resultAbort, true);
12686 scheduleBroadcastsLocked();
12687
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012688 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012689 // Post the ANR to the handler since we do not want to process ANRs while
12690 // potentially holding our lock.
12691 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012692 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012693 }
12694
12695 private final void processCurBroadcastLocked(BroadcastRecord r,
12696 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012697 if (DEBUG_BROADCAST) Slog.v(TAG,
12698 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012699 if (app.thread == null) {
12700 throw new RemoteException();
12701 }
12702 r.receiver = app.thread.asBinder();
12703 r.curApp = app;
12704 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012705 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012706
12707 // Tell the application to launch this receiver.
12708 r.intent.setComponent(r.curComponent);
12709
12710 boolean started = false;
12711 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012712 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012713 "Delivering to component " + r.curComponent
12714 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012715 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012716 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012717 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012718 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012719 if (DEBUG_BROADCAST) Slog.v(TAG,
12720 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012721 started = true;
12722 } finally {
12723 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012724 if (DEBUG_BROADCAST) Slog.v(TAG,
12725 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012726 r.receiver = null;
12727 r.curApp = null;
12728 app.curReceiver = null;
12729 }
12730 }
12731
12732 }
12733
Jeff Brown4d94a762010-09-23 11:33:28 -070012734 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012735 Intent intent, int resultCode, String data, Bundle extras,
12736 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012737 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012738 if (app != null && app.thread != null) {
12739 // If we have an app thread, do the call through that so it is
12740 // correctly ordered with other one-way calls.
12741 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012742 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012743 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012744 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012745 }
12746 }
12747
Jeff Brown4d94a762010-09-23 11:33:28 -070012748 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012749 BroadcastFilter filter, boolean ordered) {
12750 boolean skip = false;
12751 if (filter.requiredPermission != null) {
12752 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012753 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012754 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012755 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012756 + r.intent.toString()
12757 + " from " + r.callerPackage + " (pid="
12758 + r.callingPid + ", uid=" + r.callingUid + ")"
12759 + " requires " + filter.requiredPermission
12760 + " due to registered receiver " + filter);
12761 skip = true;
12762 }
12763 }
12764 if (r.requiredPermission != null) {
12765 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012766 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012767 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012768 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012769 + r.intent.toString()
12770 + " to " + filter.receiverList.app
12771 + " (pid=" + filter.receiverList.pid
12772 + ", uid=" + filter.receiverList.uid + ")"
12773 + " requires " + r.requiredPermission
12774 + " due to sender " + r.callerPackage
12775 + " (uid " + r.callingUid + ")");
12776 skip = true;
12777 }
12778 }
12779
12780 if (!skip) {
12781 // If this is not being sent as an ordered broadcast, then we
12782 // don't want to touch the fields that keep track of the current
12783 // state of ordered broadcasts.
12784 if (ordered) {
12785 r.receiver = filter.receiverList.receiver.asBinder();
12786 r.curFilter = filter;
12787 filter.receiverList.curBroadcast = r;
12788 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012789 if (filter.receiverList.app != null) {
12790 // Bump hosting application to no longer be in background
12791 // scheduling class. Note that we can't do that if there
12792 // isn't an app... but we can only be in that case for
12793 // things that directly call the IActivityManager API, which
12794 // are already core system stuff so don't matter for this.
12795 r.curApp = filter.receiverList.app;
12796 filter.receiverList.app.curReceiver = r;
12797 updateOomAdjLocked();
12798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012799 }
12800 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012801 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012802 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012803 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012804 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012805 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012806 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012807 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012808 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012809 if (ordered) {
12810 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12811 }
12812 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012813 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012814 if (ordered) {
12815 r.receiver = null;
12816 r.curFilter = null;
12817 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012818 if (filter.receiverList.app != null) {
12819 filter.receiverList.app.curReceiver = null;
12820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012821 }
12822 }
12823 }
12824 }
12825
Dianne Hackborn12527f92009-11-11 17:39:50 -080012826 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12827 if (r.callingUid < 0) {
12828 // This was from a registerReceiver() call; ignore it.
12829 return;
12830 }
12831 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12832 MAX_BROADCAST_HISTORY-1);
12833 r.finishTime = SystemClock.uptimeMillis();
12834 mBroadcastHistory[0] = r;
12835 }
12836
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012837 private final void processNextBroadcast(boolean fromMsg) {
12838 synchronized(this) {
12839 BroadcastRecord r;
12840
Joe Onorato8a9b2202010-02-26 18:56:32 -080012841 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012842 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012843 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012844
12845 updateCpuStats();
12846
12847 if (fromMsg) {
12848 mBroadcastsScheduled = false;
12849 }
12850
12851 // First, deliver any non-serialized broadcasts right away.
12852 while (mParallelBroadcasts.size() > 0) {
12853 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012854 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012855 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012856 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012857 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012858 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012859 for (int i=0; i<N; i++) {
12860 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012861 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012862 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012863 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012864 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012865 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012866 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012867 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012868 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012869 }
12870
12871 // Now take care of the next serialized one...
12872
12873 // If we are waiting for a process to come up to handle the next
12874 // broadcast, then do nothing at this point. Just in case, we
12875 // check that the process we're waiting for still exists.
12876 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012877 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012878 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012879 + mPendingBroadcast.curApp);
12880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012881
12882 boolean isDead;
12883 synchronized (mPidsSelfLocked) {
12884 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12885 }
12886 if (!isDead) {
12887 // It's still alive, so keep waiting
12888 return;
12889 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012890 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012891 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012892 mPendingBroadcast.state = BroadcastRecord.IDLE;
12893 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012894 mPendingBroadcast = null;
12895 }
12896 }
12897
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012898 boolean looped = false;
12899
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012900 do {
12901 if (mOrderedBroadcasts.size() == 0) {
12902 // No more broadcasts pending, so all done!
12903 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012904 if (looped) {
12905 // If we had finished the last ordered broadcast, then
12906 // make sure all processes have correct oom and sched
12907 // adjustments.
12908 updateOomAdjLocked();
12909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012910 return;
12911 }
12912 r = mOrderedBroadcasts.get(0);
12913 boolean forceReceive = false;
12914
12915 // Ensure that even if something goes awry with the timeout
12916 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012917 // and continue to make progress.
12918 //
12919 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012920 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012921 // one time heavy lifting after system upgrades and can take
12922 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012923 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012924 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012925 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012926 if ((numReceivers > 0) &&
12927 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012928 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012929 + " now=" + now
12930 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012931 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012932 + " intent=" + r.intent
12933 + " numReceivers=" + numReceivers
12934 + " nextReceiver=" + r.nextReceiver
12935 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012936 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012937 forceReceive = true;
12938 r.state = BroadcastRecord.IDLE;
12939 }
12940 }
12941
12942 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012943 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012944 "processNextBroadcast() called when not idle (state="
12945 + r.state + ")");
12946 return;
12947 }
12948
12949 if (r.receivers == null || r.nextReceiver >= numReceivers
12950 || r.resultAbort || forceReceive) {
12951 // No more receivers for this broadcast! Send the final
12952 // result if requested...
12953 if (r.resultTo != null) {
12954 try {
12955 if (DEBUG_BROADCAST) {
12956 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012957 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012958 + " seq=" + seq + " app=" + r.callerApp);
12959 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012960 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012961 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012962 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012963 // Set this to null so that the reference
12964 // (local and remote) isnt kept in the mBroadcastHistory.
12965 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012966 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012967 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012968 }
12969 }
12970
Joe Onorato8a9b2202010-02-26 18:56:32 -080012971 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012972 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012973
Joe Onorato8a9b2202010-02-26 18:56:32 -080012974 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012975 + r);
12976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012977 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012978 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012979 mOrderedBroadcasts.remove(0);
12980 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012981 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012982 continue;
12983 }
12984 } while (r == null);
12985
12986 // Get the next receiver...
12987 int recIdx = r.nextReceiver++;
12988
12989 // Keep track of when this receiver started, and make sure there
12990 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012991 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012992 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012993 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012994 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012995 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012996 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012997 }
12998 if (! mPendingBroadcastTimeoutMessage) {
12999 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013000 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070013001 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
13002 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013003 }
13004
13005 Object nextReceiver = r.receivers.get(recIdx);
13006 if (nextReceiver instanceof BroadcastFilter) {
13007 // Simple case: this is a registered receiver who gets
13008 // a direct call.
13009 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013010 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013011 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013012 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070013013 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013014 if (r.receiver == null || !r.ordered) {
13015 // The receiver has already finished, so schedule to
13016 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013017 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
13018 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013019 r.state = BroadcastRecord.IDLE;
13020 scheduleBroadcastsLocked();
13021 }
13022 return;
13023 }
13024
13025 // Hard case: need to instantiate the receiver, possibly
13026 // starting its application process to host it.
13027
13028 ResolveInfo info =
13029 (ResolveInfo)nextReceiver;
13030
13031 boolean skip = false;
13032 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013033 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
13034 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013035 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013036 if (!info.activityInfo.exported) {
13037 Slog.w(TAG, "Permission Denial: broadcasting "
13038 + r.intent.toString()
13039 + " from " + r.callerPackage + " (pid=" + r.callingPid
13040 + ", uid=" + r.callingUid + ")"
13041 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
13042 + " due to receiver " + info.activityInfo.packageName
13043 + "/" + info.activityInfo.name);
13044 } else {
13045 Slog.w(TAG, "Permission Denial: broadcasting "
13046 + r.intent.toString()
13047 + " from " + r.callerPackage + " (pid=" + r.callingPid
13048 + ", uid=" + r.callingUid + ")"
13049 + " requires " + info.activityInfo.permission
13050 + " due to receiver " + info.activityInfo.packageName
13051 + "/" + info.activityInfo.name);
13052 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013053 skip = true;
13054 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070013055 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013056 r.requiredPermission != null) {
13057 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013058 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013059 checkPermission(r.requiredPermission,
13060 info.activityInfo.applicationInfo.packageName);
13061 } catch (RemoteException e) {
13062 perm = PackageManager.PERMISSION_DENIED;
13063 }
13064 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013065 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013066 + r.intent + " to "
13067 + info.activityInfo.applicationInfo.packageName
13068 + " requires " + r.requiredPermission
13069 + " due to sender " + r.callerPackage
13070 + " (uid " + r.callingUid + ")");
13071 skip = true;
13072 }
13073 }
13074 if (r.curApp != null && r.curApp.crashing) {
13075 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013076 if (DEBUG_BROADCAST) Slog.v(TAG,
13077 "Skipping deliver ordered " + r + " to " + r.curApp
13078 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013079 skip = true;
13080 }
13081
13082 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013083 if (DEBUG_BROADCAST) Slog.v(TAG,
13084 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013085 r.receiver = null;
13086 r.curFilter = null;
13087 r.state = BroadcastRecord.IDLE;
13088 scheduleBroadcastsLocked();
13089 return;
13090 }
13091
13092 r.state = BroadcastRecord.APP_RECEIVE;
13093 String targetProcess = info.activityInfo.processName;
13094 r.curComponent = new ComponentName(
13095 info.activityInfo.applicationInfo.packageName,
13096 info.activityInfo.name);
13097 r.curReceiver = info.activityInfo;
13098
Dianne Hackborne7f97212011-02-24 14:40:20 -080013099 // Broadcast is being executed, its package can't be stopped.
13100 try {
13101 AppGlobals.getPackageManager().setPackageStoppedState(
13102 r.curComponent.getPackageName(), false);
13103 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080013104 } catch (IllegalArgumentException e) {
13105 Slog.w(TAG, "Failed trying to unstop package "
13106 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080013107 }
13108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013109 // Is this receiver's application already running?
13110 ProcessRecord app = getProcessRecordLocked(targetProcess,
13111 info.activityInfo.applicationInfo.uid);
13112 if (app != null && app.thread != null) {
13113 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070013114 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013115 processCurBroadcastLocked(r, app);
13116 return;
13117 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013118 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013119 + r.curComponent, e);
13120 }
13121
13122 // If a dead object exception was thrown -- fall through to
13123 // restart the application.
13124 }
13125
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013126 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013127 if (DEBUG_BROADCAST) Slog.v(TAG,
13128 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013129 if ((r.curApp=startProcessLocked(targetProcess,
13130 info.activityInfo.applicationInfo, true,
13131 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013132 "broadcast", r.curComponent,
13133 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
13134 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013135 // Ah, this recipient is unavailable. Finish it if necessary,
13136 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013137 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013138 + info.activityInfo.applicationInfo.packageName + "/"
13139 + info.activityInfo.applicationInfo.uid + " for broadcast "
13140 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070013141 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013142 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
13143 r.resultExtras, r.resultAbort, true);
13144 scheduleBroadcastsLocked();
13145 r.state = BroadcastRecord.IDLE;
13146 return;
13147 }
13148
13149 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013150 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013151 }
13152 }
13153
13154 // =========================================================
13155 // INSTRUMENTATION
13156 // =========================================================
13157
13158 public boolean startInstrumentation(ComponentName className,
13159 String profileFile, int flags, Bundle arguments,
13160 IInstrumentationWatcher watcher) {
13161 // Refuse possible leaked file descriptors
13162 if (arguments != null && arguments.hasFileDescriptors()) {
13163 throw new IllegalArgumentException("File descriptors passed in Bundle");
13164 }
13165
13166 synchronized(this) {
13167 InstrumentationInfo ii = null;
13168 ApplicationInfo ai = null;
13169 try {
13170 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013171 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013172 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013173 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013174 } catch (PackageManager.NameNotFoundException e) {
13175 }
13176 if (ii == null) {
13177 reportStartInstrumentationFailure(watcher, className,
13178 "Unable to find instrumentation info for: " + className);
13179 return false;
13180 }
13181 if (ai == null) {
13182 reportStartInstrumentationFailure(watcher, className,
13183 "Unable to find instrumentation target package: " + ii.targetPackage);
13184 return false;
13185 }
13186
13187 int match = mContext.getPackageManager().checkSignatures(
13188 ii.targetPackage, ii.packageName);
13189 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13190 String msg = "Permission Denial: starting instrumentation "
13191 + className + " from pid="
13192 + Binder.getCallingPid()
13193 + ", uid=" + Binder.getCallingPid()
13194 + " not allowed because package " + ii.packageName
13195 + " does not have a signature matching the target "
13196 + ii.targetPackage;
13197 reportStartInstrumentationFailure(watcher, className, msg);
13198 throw new SecurityException(msg);
13199 }
13200
13201 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070013202 // Instrumentation can kill and relaunch even persistent processes
13203 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013204 ProcessRecord app = addAppLocked(ai);
13205 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013206 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013207 app.instrumentationProfileFile = profileFile;
13208 app.instrumentationArguments = arguments;
13209 app.instrumentationWatcher = watcher;
13210 app.instrumentationResultClass = className;
13211 Binder.restoreCallingIdentity(origId);
13212 }
13213
13214 return true;
13215 }
13216
13217 /**
13218 * Report errors that occur while attempting to start Instrumentation. Always writes the
13219 * error to the logs, but if somebody is watching, send the report there too. This enables
13220 * the "am" command to report errors with more information.
13221 *
13222 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
13223 * @param cn The component name of the instrumentation.
13224 * @param report The error report.
13225 */
13226 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13227 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013228 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013229 try {
13230 if (watcher != null) {
13231 Bundle results = new Bundle();
13232 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13233 results.putString("Error", report);
13234 watcher.instrumentationStatus(cn, -1, results);
13235 }
13236 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013237 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013238 }
13239 }
13240
13241 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13242 if (app.instrumentationWatcher != null) {
13243 try {
13244 // NOTE: IInstrumentationWatcher *must* be oneway here
13245 app.instrumentationWatcher.instrumentationFinished(
13246 app.instrumentationClass,
13247 resultCode,
13248 results);
13249 } catch (RemoteException e) {
13250 }
13251 }
13252 app.instrumentationWatcher = null;
13253 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013254 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013255 app.instrumentationProfileFile = null;
13256 app.instrumentationArguments = null;
13257
Christopher Tate3dacd842011-08-19 14:56:15 -070013258 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013259 }
13260
13261 public void finishInstrumentation(IApplicationThread target,
13262 int resultCode, Bundle results) {
13263 // Refuse possible leaked file descriptors
13264 if (results != null && results.hasFileDescriptors()) {
13265 throw new IllegalArgumentException("File descriptors passed in Intent");
13266 }
13267
13268 synchronized(this) {
13269 ProcessRecord app = getRecordForAppLocked(target);
13270 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013271 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013272 return;
13273 }
13274 final long origId = Binder.clearCallingIdentity();
13275 finishInstrumentationLocked(app, resultCode, results);
13276 Binder.restoreCallingIdentity(origId);
13277 }
13278 }
13279
13280 // =========================================================
13281 // CONFIGURATION
13282 // =========================================================
13283
13284 public ConfigurationInfo getDeviceConfigurationInfo() {
13285 ConfigurationInfo config = new ConfigurationInfo();
13286 synchronized (this) {
13287 config.reqTouchScreen = mConfiguration.touchscreen;
13288 config.reqKeyboardType = mConfiguration.keyboard;
13289 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013290 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13291 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013292 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13293 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013294 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13295 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013296 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13297 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070013298 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013299 }
13300 return config;
13301 }
13302
13303 public Configuration getConfiguration() {
13304 Configuration ci;
13305 synchronized(this) {
13306 ci = new Configuration(mConfiguration);
13307 }
13308 return ci;
13309 }
13310
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013311 public void updatePersistentConfiguration(Configuration values) {
13312 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13313 "updateConfiguration()");
13314 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13315 "updateConfiguration()");
13316 if (values == null) {
13317 throw new NullPointerException("Configuration must not be null");
13318 }
13319
13320 synchronized(this) {
13321 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013322 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013323 Binder.restoreCallingIdentity(origId);
13324 }
13325 }
13326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013327 public void updateConfiguration(Configuration values) {
13328 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13329 "updateConfiguration()");
13330
13331 synchronized(this) {
13332 if (values == null && mWindowManager != null) {
13333 // sentinel: fetch the current configuration from the window manager
13334 values = mWindowManager.computeNewConfiguration();
13335 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013336
13337 if (mWindowManager != null) {
13338 mProcessList.applyDisplaySize(mWindowManager);
13339 }
13340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013341 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013342 if (values != null) {
13343 Settings.System.clearConfiguration(values);
13344 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013345 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013346 Binder.restoreCallingIdentity(origId);
13347 }
13348 }
13349
13350 /**
13351 * Do either or both things: (1) change the current configuration, and (2)
13352 * make sure the given activity is running with the (now) current
13353 * configuration. Returns true if the activity has been left running, or
13354 * false if <var>starting</var> is being destroyed to match the new
13355 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013356 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013357 */
13358 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013359 ActivityRecord starting, boolean persistent, boolean initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013360 int changes = 0;
13361
13362 boolean kept = true;
13363
13364 if (values != null) {
13365 Configuration newConfig = new Configuration(mConfiguration);
13366 changes = newConfig.updateFrom(values);
13367 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013368 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013369 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013370 }
13371
Doug Zongker2bec3d42009-12-04 12:52:44 -080013372 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013373
Dianne Hackborn813075a62011-11-14 17:45:19 -080013374 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013375 saveLocaleLocked(values.locale,
13376 !values.locale.equals(mConfiguration.locale),
13377 values.userSetLocale);
13378 }
13379
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013380 mConfigurationSeq++;
13381 if (mConfigurationSeq <= 0) {
13382 mConfigurationSeq = 1;
13383 }
13384 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013385 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013386 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013387
13388 final Configuration configCopy = new Configuration(mConfiguration);
13389
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013390 AttributeCache ac = AttributeCache.instance();
13391 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013392 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013394
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013395 // Make sure all resources in our process are updated
13396 // right now, so that anyone who is going to retrieve
13397 // resource values after we return will be sure to get
13398 // the new ones. This is especially important during
13399 // boot, where the first config change needs to guarantee
13400 // all resources have that config before following boot
13401 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080013402 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013403
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013404 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013405 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013406 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013407 mHandler.sendMessage(msg);
13408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013409
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013410 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13411 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013412 try {
13413 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013414 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013415 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013416 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013417 }
13418 } catch (Exception e) {
13419 }
13420 }
13421 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013422 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13423 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013424 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13425 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013426 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13427 broadcastIntentLocked(null, null,
13428 new Intent(Intent.ACTION_LOCALE_CHANGED),
13429 null, null, 0, null, null,
13430 null, false, false, MY_PID, Process.SYSTEM_UID);
13431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013432 }
13433 }
13434
13435 if (changes != 0 && starting == null) {
13436 // If the configuration changed, and the caller is not already
13437 // in the process of starting an activity, then find the top
13438 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013439 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013440 }
13441
13442 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013443 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013444 // And we need to make sure at this point that all other activities
13445 // are made visible with the correct configuration.
13446 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013447 }
13448
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013449 if (values != null && mWindowManager != null) {
13450 mWindowManager.setNewConfiguration(mConfiguration);
13451 }
13452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013453 return kept;
13454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013455
13456 /**
13457 * Save the locale. You must be inside a synchronized (this) block.
13458 */
13459 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13460 if(isDiff) {
13461 SystemProperties.set("user.language", l.getLanguage());
13462 SystemProperties.set("user.region", l.getCountry());
13463 }
13464
13465 if(isPersist) {
13466 SystemProperties.set("persist.sys.language", l.getLanguage());
13467 SystemProperties.set("persist.sys.country", l.getCountry());
13468 SystemProperties.set("persist.sys.localevar", l.getVariant());
13469 }
13470 }
13471
13472 // =========================================================
13473 // LIFETIME MANAGEMENT
13474 // =========================================================
13475
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013476 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013477 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013478 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013479 // This adjustment has already been computed. If we are calling
13480 // from the top, we may have already computed our adjustment with
13481 // an earlier hidden adjustment that isn't really for us... if
13482 // so, use the new hidden adjustment.
13483 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013484 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013485 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013486 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013487 }
13488
13489 if (app.thread == null) {
13490 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013491 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013492 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013493 }
13494
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013495 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13496 app.adjSource = null;
13497 app.adjTarget = null;
13498 app.empty = false;
13499 app.hidden = false;
13500
13501 final int activitiesSize = app.activities.size();
13502
Dianne Hackborn7d608422011-08-07 16:24:18 -070013503 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013504 // The max adjustment doesn't allow this app to be anything
13505 // below foreground, so it is not worth doing work for it.
13506 app.adjType = "fixed";
13507 app.adjSeq = mAdjSeq;
13508 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013509 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013510 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013511 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013512 // System process can do UI, and when they do we want to have
13513 // them trim their memory after the user leaves the UI. To
13514 // facilitate this, here we need to determine whether or not it
13515 // is currently showing UI.
13516 app.systemNoUi = true;
13517 if (app == TOP_APP) {
13518 app.systemNoUi = false;
13519 } else if (activitiesSize > 0) {
13520 for (int j = 0; j < activitiesSize; j++) {
13521 final ActivityRecord r = app.activities.get(j);
13522 if (r.visible) {
13523 app.systemNoUi = false;
13524 break;
13525 }
13526 }
13527 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013528 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013529 }
13530
13531 final boolean hadForegroundActivities = app.foregroundActivities;
13532
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013533 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013534 app.keeping = false;
13535 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013536
The Android Open Source Project4df24232009-03-05 14:34:35 -080013537 // Determine the importance of the process, starting with most
13538 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013539 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013540 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013541 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013542 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013543 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013544 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013545 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013546 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013547 } else if (app.instrumentationClass != null) {
13548 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013549 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013550 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013551 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013552 } else if (app.curReceiver != null ||
13553 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13554 // An app that is currently receiving a broadcast also
13555 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013556 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013557 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013558 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013559 } else if (app.executingServices.size() > 0) {
13560 // An app that is currently executing a service callback also
13561 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013562 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013563 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013564 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013565 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013566 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013567 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013568 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013569 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013570 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013571 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013572 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013573 // A very not-needed process. If this is lower in the lru list,
13574 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013575 adj = hiddenAdj;
13576 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013577 app.hidden = true;
13578 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013579 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013580 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013581
13582 // Examine all activities if not already foreground.
13583 if (!app.foregroundActivities && activitiesSize > 0) {
13584 for (int j = 0; j < activitiesSize; j++) {
13585 final ActivityRecord r = app.activities.get(j);
13586 if (r.visible) {
13587 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013588 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13589 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013590 app.adjType = "visible";
13591 }
13592 schedGroup = Process.THREAD_GROUP_DEFAULT;
13593 app.hidden = false;
13594 app.foregroundActivities = true;
13595 break;
13596 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13597 || r.state == ActivityState.STOPPING) {
13598 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013599 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13600 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013601 app.adjType = "stopping";
13602 }
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -080013603 app.hidden = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013604 app.foregroundActivities = true;
13605 }
13606 }
13607 }
13608
Dianne Hackborn7d608422011-08-07 16:24:18 -070013609 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013610 if (app.foregroundServices) {
13611 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013612 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013613 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013614 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013615 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013616 } else if (app.forcingToForeground != null) {
13617 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013618 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013619 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013620 app.adjType = "force-foreground";
13621 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013622 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013623 }
13624 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013625
Dianne Hackborn7d608422011-08-07 16:24:18 -070013626 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013627 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013628 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013629 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013630 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013631 app.adjType = "heavy";
13632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013633
Dianne Hackborn7d608422011-08-07 16:24:18 -070013634 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013635 // This process is hosting what we currently consider to be the
13636 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013637 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013638 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013639 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013640 app.adjType = "home";
13641 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013642
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013643 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13644 && app.activities.size() > 0) {
13645 // This was the previous process that showed UI to the user.
13646 // We want to try to keep it around more aggressively, to give
13647 // a good experience around switching between two apps.
13648 adj = ProcessList.PREVIOUS_APP_ADJ;
13649 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13650 app.hidden = false;
13651 app.adjType = "previous";
13652 }
13653
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013654 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13655 + " reason=" + app.adjType);
13656
The Android Open Source Project4df24232009-03-05 14:34:35 -080013657 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013658 // there are applications dependent on our services or providers, but
13659 // this gives us a baseline and makes sure we don't get into an
13660 // infinite recursion.
13661 app.adjSeq = mAdjSeq;
13662 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013663
Christopher Tate6fa95972009-06-05 18:43:55 -070013664 if (mBackupTarget != null && app == mBackupTarget.app) {
13665 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013666 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013667 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013668 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013669 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013670 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013671 }
13672 }
13673
Dianne Hackborn7d608422011-08-07 16:24:18 -070013674 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013675 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013676 final long now = SystemClock.uptimeMillis();
13677 // This process is more important if the top activity is
13678 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013679 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013680 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013681 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013682 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013683 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013684 // If this process has shown some UI, let it immediately
13685 // go to the LRU list because it may be pretty heavy with
13686 // UI stuff. We'll tag it with a label just to help
13687 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013688 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013689 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013690 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013691 } else {
13692 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13693 // This service has seen some activity within
13694 // recent memory, so we will keep its process ahead
13695 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013696 if (adj > ProcessList.SERVICE_ADJ) {
13697 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013698 app.adjType = "started-services";
13699 app.hidden = false;
13700 }
13701 }
13702 // If we have let the service slide into the background
13703 // state, still have some text describing what it is doing
13704 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013705 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013706 app.adjType = "started-bg-services";
13707 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013708 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013709 // Don't kill this process because it is doing work; it
13710 // has said it is doing work.
13711 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013712 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013713 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013714 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013715 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013716 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013717 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013718 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013719 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013720 // XXX should compute this based on the max of
13721 // all connected clients.
13722 ConnectionRecord cr = clist.get(i);
13723 if (cr.binding.client == app) {
13724 // Binding to ourself is not interesting.
13725 continue;
13726 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013727 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013728 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013729 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013730 int myHiddenAdj = hiddenAdj;
13731 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013732 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013733 myHiddenAdj = client.hiddenAdj;
13734 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013735 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013736 }
13737 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013738 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013739 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013740 String adjType = null;
13741 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13742 // Not doing bind OOM management, so treat
13743 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013744 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013745 // If this process has shown some UI, let it immediately
13746 // go to the LRU list because it may be pretty heavy with
13747 // UI stuff. We'll tag it with a label just to help
13748 // debug and understand what is going on.
13749 if (adj > clientAdj) {
13750 adjType = "bound-bg-ui-services";
13751 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013752 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013753 clientAdj = adj;
13754 } else {
13755 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13756 // This service has not seen activity within
13757 // recent memory, so allow it to drop to the
13758 // LRU list if there is no other reason to keep
13759 // it around. We'll also tag it with a label just
13760 // to help debug and undertand what is going on.
13761 if (adj > clientAdj) {
13762 adjType = "bound-bg-services";
13763 }
13764 clientAdj = adj;
13765 }
13766 }
13767 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013768 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013769 // If this process has recently shown UI, and
13770 // the process that is binding to it is less
13771 // important than being visible, then we don't
13772 // care about the binding as much as we care
13773 // about letting this process get into the LRU
13774 // list to be killed and restarted if needed for
13775 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013776 if (app.hasShownUi && app != mHomeProcess
13777 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013778 adjType = "bound-bg-ui-services";
13779 } else {
13780 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13781 |Context.BIND_IMPORTANT)) != 0) {
13782 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013783 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13784 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13785 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13786 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13787 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013788 adj = clientAdj;
13789 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013790 app.pendingUiClean = true;
13791 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13792 adj = ProcessList.VISIBLE_APP_ADJ;
13793 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013794 }
13795 if (!client.hidden) {
13796 app.hidden = false;
13797 }
13798 if (client.keeping) {
13799 app.keeping = true;
13800 }
13801 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013802 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013803 }
13804 if (adjType != null) {
13805 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013806 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13807 .REASON_SERVICE_IN_USE;
13808 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013809 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013810 app.adjTarget = s.name;
13811 }
13812 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13813 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13814 schedGroup = Process.THREAD_GROUP_DEFAULT;
13815 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013816 }
13817 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013818 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13819 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013820 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013821 (a.visible || a.state == ActivityState.RESUMED
13822 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013823 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013824 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13825 schedGroup = Process.THREAD_GROUP_DEFAULT;
13826 }
13827 app.hidden = false;
13828 app.adjType = "service";
13829 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13830 .REASON_SERVICE_IN_USE;
13831 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013832 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013833 app.adjTarget = s.name;
13834 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013835 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013836 }
13837 }
13838 }
13839 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013840
Dianne Hackborn287952c2010-09-22 22:34:31 -070013841 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013842 // would like to avoid killing it unless it would prevent the current
13843 // application from running. By default we put the process in
13844 // with the rest of the background processes; as we scan through
13845 // its services we may bump it up from there.
13846 if (adj > hiddenAdj) {
13847 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013848 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013849 app.adjType = "bg-services";
13850 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013851 }
13852
Dianne Hackborn7d608422011-08-07 16:24:18 -070013853 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013854 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013855 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013856 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013857 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013858 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013859 if (cpr.clients.size() != 0) {
13860 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013861 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013862 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013863 if (client == app) {
13864 // Being our own client is not interesting.
13865 continue;
13866 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013867 int myHiddenAdj = hiddenAdj;
13868 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013869 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013870 myHiddenAdj = client.hiddenAdj;
13871 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013872 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013873 }
13874 }
13875 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013876 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013877 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013878 if (app.hasShownUi && app != mHomeProcess
13879 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013880 app.adjType = "bg-ui-provider";
13881 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013882 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13883 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013884 app.adjType = "provider";
13885 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013886 if (!client.hidden) {
13887 app.hidden = false;
13888 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013889 if (client.keeping) {
13890 app.keeping = true;
13891 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013892 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13893 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013894 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013895 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013896 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013897 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013898 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13899 schedGroup = Process.THREAD_GROUP_DEFAULT;
13900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013901 }
13902 }
13903 // If the provider has external (non-framework) process
13904 // dependencies, ensure that its adjustment is at least
13905 // FOREGROUND_APP_ADJ.
13906 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013907 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13908 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013909 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013910 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013911 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013912 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013913 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013914 }
13915 }
13916 }
13917 }
13918
13919 app.curRawAdj = adj;
13920
Joe Onorato8a9b2202010-02-26 18:56:32 -080013921 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013922 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13923 if (adj > app.maxAdj) {
13924 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013925 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013926 schedGroup = Process.THREAD_GROUP_DEFAULT;
13927 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013928 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013929 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013930 app.keeping = true;
13931 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013932
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013933 if (app.hasAboveClient) {
13934 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13935 // then we need to drop its adjustment to be lower than the service's
13936 // in order to honor the request. We want to drop it by one adjustment
13937 // level... but there is special meaning applied to various levels so
13938 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013939 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013940 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013941 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13942 adj = ProcessList.VISIBLE_APP_ADJ;
13943 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13944 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13945 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13946 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013947 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013948 adj++;
13949 }
13950 }
13951
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013952 if (adj == ProcessList.SERVICE_ADJ) {
13953 if (doingAll) {
13954 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13955 mNewNumServiceProcs++;
13956 }
13957 if (app.serviceb) {
13958 adj = ProcessList.SERVICE_B_ADJ;
13959 }
13960 } else {
13961 app.serviceb = false;
13962 }
13963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013964 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013965 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013966
13967 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013968 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13969 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013970 }
13971
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013972 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013973 }
13974
13975 /**
13976 * Ask a given process to GC right now.
13977 */
13978 final void performAppGcLocked(ProcessRecord app) {
13979 try {
13980 app.lastRequestedGc = SystemClock.uptimeMillis();
13981 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013982 if (app.reportLowMemory) {
13983 app.reportLowMemory = false;
13984 app.thread.scheduleLowMemory();
13985 } else {
13986 app.thread.processInBackground();
13987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013988 }
13989 } catch (Exception e) {
13990 // whatever.
13991 }
13992 }
13993
13994 /**
13995 * Returns true if things are idle enough to perform GCs.
13996 */
Josh Bartel7f208742010-02-25 11:01:44 -060013997 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013998 return mParallelBroadcasts.size() == 0
13999 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014000 && (mSleeping || (mMainStack.mResumedActivity != null &&
14001 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014002 }
14003
14004 /**
14005 * Perform GCs on all processes that are waiting for it, but only
14006 * if things are idle.
14007 */
14008 final void performAppGcsLocked() {
14009 final int N = mProcessesToGc.size();
14010 if (N <= 0) {
14011 return;
14012 }
Josh Bartel7f208742010-02-25 11:01:44 -060014013 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014014 while (mProcessesToGc.size() > 0) {
14015 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014016 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014017 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14018 <= SystemClock.uptimeMillis()) {
14019 // To avoid spamming the system, we will GC processes one
14020 // at a time, waiting a few seconds between each.
14021 performAppGcLocked(proc);
14022 scheduleAppGcsLocked();
14023 return;
14024 } else {
14025 // It hasn't been long enough since we last GCed this
14026 // process... put it in the list to wait for its time.
14027 addProcessToGcListLocked(proc);
14028 break;
14029 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014030 }
14031 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014032
14033 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014034 }
14035 }
14036
14037 /**
14038 * If all looks good, perform GCs on all processes waiting for them.
14039 */
14040 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060014041 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014042 performAppGcsLocked();
14043 return;
14044 }
14045 // Still not idle, wait some more.
14046 scheduleAppGcsLocked();
14047 }
14048
14049 /**
14050 * Schedule the execution of all pending app GCs.
14051 */
14052 final void scheduleAppGcsLocked() {
14053 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014054
14055 if (mProcessesToGc.size() > 0) {
14056 // Schedule a GC for the time to the next process.
14057 ProcessRecord proc = mProcessesToGc.get(0);
14058 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14059
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014060 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014061 long now = SystemClock.uptimeMillis();
14062 if (when < (now+GC_TIMEOUT)) {
14063 when = now + GC_TIMEOUT;
14064 }
14065 mHandler.sendMessageAtTime(msg, when);
14066 }
14067 }
14068
14069 /**
14070 * Add a process to the array of processes waiting to be GCed. Keeps the
14071 * list in sorted order by the last GC time. The process can't already be
14072 * on the list.
14073 */
14074 final void addProcessToGcListLocked(ProcessRecord proc) {
14075 boolean added = false;
14076 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14077 if (mProcessesToGc.get(i).lastRequestedGc <
14078 proc.lastRequestedGc) {
14079 added = true;
14080 mProcessesToGc.add(i+1, proc);
14081 break;
14082 }
14083 }
14084 if (!added) {
14085 mProcessesToGc.add(0, proc);
14086 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014087 }
14088
14089 /**
14090 * Set up to ask a process to GC itself. This will either do it
14091 * immediately, or put it on the list of processes to gc the next
14092 * time things are idle.
14093 */
14094 final void scheduleAppGcLocked(ProcessRecord app) {
14095 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014096 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014097 return;
14098 }
14099 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014100 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014101 scheduleAppGcsLocked();
14102 }
14103 }
14104
Dianne Hackborn287952c2010-09-22 22:34:31 -070014105 final void checkExcessivePowerUsageLocked(boolean doKills) {
14106 updateCpuStatsNow();
14107
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014108 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014109 boolean doWakeKills = doKills;
14110 boolean doCpuKills = doKills;
14111 if (mLastPowerCheckRealtime == 0) {
14112 doWakeKills = false;
14113 }
14114 if (mLastPowerCheckUptime == 0) {
14115 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014116 }
14117 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014118 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014119 }
14120 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014121 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14122 final long curUptime = SystemClock.uptimeMillis();
14123 final long uptimeSince = curUptime - mLastPowerCheckUptime;
14124 mLastPowerCheckRealtime = curRealtime;
14125 mLastPowerCheckUptime = curUptime;
14126 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14127 doWakeKills = false;
14128 }
14129 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14130 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014131 }
14132 int i = mLruProcesses.size();
14133 while (i > 0) {
14134 i--;
14135 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014136 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014137 long wtime;
14138 synchronized (stats) {
14139 wtime = stats.getProcessWakeTime(app.info.uid,
14140 app.pid, curRealtime);
14141 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014142 long wtimeUsed = wtime - app.lastWakeTime;
14143 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14144 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014145 StringBuilder sb = new StringBuilder(128);
14146 sb.append("Wake for ");
14147 app.toShortString(sb);
14148 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014149 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014150 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014151 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014152 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014153 sb.append((wtimeUsed*100)/realtimeSince);
14154 sb.append("%)");
14155 Slog.i(TAG, sb.toString());
14156 sb.setLength(0);
14157 sb.append("CPU for ");
14158 app.toShortString(sb);
14159 sb.append(": over ");
14160 TimeUtils.formatDuration(uptimeSince, sb);
14161 sb.append(" used ");
14162 TimeUtils.formatDuration(cputimeUsed, sb);
14163 sb.append(" (");
14164 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014165 sb.append("%)");
14166 Slog.i(TAG, sb.toString());
14167 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014168 // If a process has held a wake lock for more
14169 // than 50% of the time during this period,
14170 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070014171 if (doWakeKills && realtimeSince > 0
14172 && ((wtimeUsed*100)/realtimeSince) >= 50) {
14173 synchronized (stats) {
14174 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14175 realtimeSince, wtimeUsed);
14176 }
14177 Slog.w(TAG, "Excessive wake lock in " + app.processName
14178 + " (pid " + app.pid + "): held " + wtimeUsed
14179 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014180 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14181 app.processName, app.setAdj, "excessive wake lock");
14182 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014183 } else if (doCpuKills && uptimeSince > 0
14184 && ((cputimeUsed*100)/uptimeSince) >= 50) {
14185 synchronized (stats) {
14186 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14187 uptimeSince, cputimeUsed);
14188 }
14189 Slog.w(TAG, "Excessive CPU in " + app.processName
14190 + " (pid " + app.pid + "): used " + cputimeUsed
14191 + " during " + uptimeSince);
14192 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14193 app.processName, app.setAdj, "excessive cpu");
14194 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014195 } else {
14196 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014197 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014198 }
14199 }
14200 }
14201 }
14202
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014203 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014204 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014205 app.hiddenAdj = hiddenAdj;
14206
14207 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014208 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014209 }
14210
Dianne Hackborn287952c2010-09-22 22:34:31 -070014211 final boolean wasKeeping = app.keeping;
14212
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014213 boolean success = true;
14214
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014215 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014216
Jeff Brown10e89712011-07-08 18:52:57 -070014217 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070014218 if (false) {
14219 // Removing for now. Forcing GCs is not so useful anymore
14220 // with Dalvik, and the new memory level hint facility is
14221 // better for what we need to do these days.
14222 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
14223 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14224 // If this app is transitioning from foreground to
14225 // non-foreground, have it do a gc.
14226 scheduleAppGcLocked(app);
14227 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14228 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14229 // Likewise do a gc when an app is moving in to the
14230 // background (such as a service stopping).
14231 scheduleAppGcLocked(app);
14232 }
Jeff Brown10e89712011-07-08 18:52:57 -070014233 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014234
Jeff Brown10e89712011-07-08 18:52:57 -070014235 if (wasKeeping && !app.keeping) {
14236 // This app is no longer something we want to keep. Note
14237 // its current wake lock time to later know to kill it if
14238 // it is not behaving well.
14239 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14240 synchronized (stats) {
14241 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14242 app.pid, SystemClock.elapsedRealtime());
14243 }
14244 app.lastCpuTime = app.curCpuTime;
14245 }
14246
14247 app.setRawAdj = app.curRawAdj;
14248 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014249
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014250 if (app.curAdj != app.setAdj) {
14251 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014252 if (true || DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
14253 TAG, "Set " + app.pid + " " + app.processName +
14254 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014255 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070014256 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014257 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014258 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070014259 }
14260 }
14261 if (app.setSchedGroup != app.curSchedGroup) {
14262 app.setSchedGroup = app.curSchedGroup;
14263 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14264 "Setting process group of " + app.processName
14265 + " to " + app.curSchedGroup);
14266 if (app.waitingToKill != null &&
14267 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14268 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14269 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14270 app.processName, app.setAdj, app.waitingToKill);
14271 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014272 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070014273 } else {
14274 if (true) {
14275 long oldId = Binder.clearCallingIdentity();
14276 try {
14277 Process.setProcessGroup(app.pid, app.curSchedGroup);
14278 } catch (Exception e) {
14279 Slog.w(TAG, "Failed setting process group of " + app.pid
14280 + " to " + app.curSchedGroup);
14281 e.printStackTrace();
14282 } finally {
14283 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014284 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014285 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070014286 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014287 try {
Jeff Brown10e89712011-07-08 18:52:57 -070014288 app.thread.setSchedulingGroup(app.curSchedGroup);
14289 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014290 }
14291 }
14292 }
14293 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014294 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014295 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014296 }
14297
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014298 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014299 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014300 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014301 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014302 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014303 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014304 }
14305 }
14306 return resumedActivity;
14307 }
14308
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014309 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014310 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014311 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14312 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014313 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14314 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014315
14316 mAdjSeq++;
14317
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014318 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014319 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14320 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014321 if (nowHidden != wasHidden) {
14322 // Changed to/from hidden state, so apps after it in the LRU
14323 // list may also be changed.
14324 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014325 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014326 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014327 }
14328
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014329 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014330 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014331 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14332
14333 if (false) {
14334 RuntimeException e = new RuntimeException();
14335 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014336 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014337 }
14338
14339 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014340 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014341
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014342 // Let's determine how many processes we have running vs.
14343 // how many slots we have for background processes; we may want
14344 // to put multiple processes in a slot of there are enough of
14345 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014346 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014347 int factor = (mLruProcesses.size()-4)/numSlots;
14348 if (factor < 1) factor = 1;
14349 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014350 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014351
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014352 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014353 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014354 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014355 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014356 while (i > 0) {
14357 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014358 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080014359 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014360 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14361 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014362 && app.curAdj == curHiddenAdj) {
14363 step++;
14364 if (step >= factor) {
14365 step = 0;
14366 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014367 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014368 }
14369 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014370 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014371 numHidden++;
14372 if (numHidden > mProcessLimit) {
14373 Slog.i(TAG, "No longer want " + app.processName
14374 + " (pid " + app.pid + "): hidden #" + numHidden);
14375 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14376 app.processName, app.setAdj, "too many background");
14377 app.killedBackground = true;
14378 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070014379 }
14380 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014381 }
14382 }
14383
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014384 mNumServiceProcs = mNewNumServiceProcs;
14385
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014386 // Now determine the memory trimming level of background processes.
14387 // Unfortunately we need to start at the back of the list to do this
14388 // properly. We only do this if the number of background apps we
14389 // are managing to keep around is less than half the maximum we desire;
14390 // if we are keeping a good number around, we'll let them use whatever
14391 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014392 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014393 final int N = mLruProcesses.size();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014394 factor = numHidden/3;
14395 int minFactor = 2;
14396 if (mHomeProcess != null) minFactor++;
14397 if (mPreviousProcess != null) minFactor++;
14398 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014399 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014400 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014401 for (i=0; i<N; i++) {
14402 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014403 if (app.curAdj >= ProcessList.HOME_APP_ADJ
14404 && app.curAdj != ProcessList.SERVICE_B_ADJ
14405 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014406 if (app.trimMemoryLevel < curLevel && app.thread != null) {
14407 try {
14408 app.thread.scheduleTrimMemory(curLevel);
14409 } catch (RemoteException e) {
14410 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014411 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014412 // For these apps we will also finish their activities
14413 // to help them free memory.
Dianne Hackborn28695e02011-11-02 21:59:51 -070014414 mMainStack.destroyActivitiesLocked(app, false, "trim");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014415 }
14416 }
14417 app.trimMemoryLevel = curLevel;
14418 step++;
14419 if (step >= factor) {
14420 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014421 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14422 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014423 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014424 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14425 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014426 break;
14427 }
14428 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014429 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014430 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014431 && app.thread != null) {
14432 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014433 app.thread.scheduleTrimMemory(
14434 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014435 } catch (RemoteException e) {
14436 }
14437 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014438 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014439 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014440 && app.pendingUiClean) {
14441 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14442 && app.thread != null) {
14443 try {
14444 app.thread.scheduleTrimMemory(
14445 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14446 } catch (RemoteException e) {
14447 }
14448 }
14449 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14450 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014451 } else {
14452 app.trimMemoryLevel = 0;
14453 }
14454 }
14455 } else {
14456 final int N = mLruProcesses.size();
14457 for (i=0; i<N; i++) {
14458 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014459 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014460 && app.pendingUiClean) {
14461 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14462 && app.thread != null) {
14463 try {
14464 app.thread.scheduleTrimMemory(
14465 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14466 } catch (RemoteException e) {
14467 }
14468 }
14469 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14470 app.pendingUiClean = false;
14471 } else {
14472 app.trimMemoryLevel = 0;
14473 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014474 }
14475 }
14476
14477 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070014478 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014479 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014480 }
14481
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014482 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014483 synchronized (this) {
14484 int i;
14485
14486 // First remove any unused application processes whose package
14487 // has been removed.
14488 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14489 final ProcessRecord app = mRemovedProcesses.get(i);
14490 if (app.activities.size() == 0
14491 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014492 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014493 TAG, "Exiting empty application process "
14494 + app.processName + " ("
14495 + (app.thread != null ? app.thread.asBinder() : null)
14496 + ")\n");
14497 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070014498 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14499 app.processName, app.setAdj, "empty");
14500 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014501 } else {
14502 try {
14503 app.thread.scheduleExit();
14504 } catch (Exception e) {
14505 // Ignore exceptions.
14506 }
14507 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014508 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014509 mRemovedProcesses.remove(i);
14510
14511 if (app.persistent) {
14512 if (app.persistent) {
14513 addAppLocked(app.info);
14514 }
14515 }
14516 }
14517 }
14518
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014519 // Now update the oom adj for all processes.
14520 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014521 }
14522 }
14523
14524 /** This method sends the specified signal to each of the persistent apps */
14525 public void signalPersistentProcesses(int sig) throws RemoteException {
14526 if (sig != Process.SIGNAL_USR1) {
14527 throw new SecurityException("Only SIGNAL_USR1 is allowed");
14528 }
14529
14530 synchronized (this) {
14531 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14532 != PackageManager.PERMISSION_GRANTED) {
14533 throw new SecurityException("Requires permission "
14534 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14535 }
14536
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014537 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14538 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014539 if (r.thread != null && r.persistent) {
14540 Process.sendSignal(r.pid, sig);
14541 }
14542 }
14543 }
14544 }
14545
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014546 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14547 if (proc == null || proc == mProfileProc) {
14548 proc = mProfileProc;
14549 path = mProfileFile;
14550 profileType = mProfileType;
14551 clearProfilerLocked();
14552 }
14553 if (proc == null) {
14554 return;
14555 }
14556 try {
14557 proc.thread.profilerControl(false, path, null, profileType);
14558 } catch (RemoteException e) {
14559 throw new IllegalStateException("Process disappeared");
14560 }
14561 }
14562
14563 private void clearProfilerLocked() {
14564 if (mProfileFd != null) {
14565 try {
14566 mProfileFd.close();
14567 } catch (IOException e) {
14568 }
14569 }
14570 mProfileApp = null;
14571 mProfileProc = null;
14572 mProfileFile = null;
14573 mProfileType = 0;
14574 mAutoStopProfiler = false;
14575 }
14576
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014577 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014578 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014579
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014580 try {
14581 synchronized (this) {
14582 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14583 // its own permission.
14584 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14585 != PackageManager.PERMISSION_GRANTED) {
14586 throw new SecurityException("Requires permission "
14587 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014588 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014589
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014590 if (start && fd == null) {
14591 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014592 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014593
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014594 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014595 if (process != null) {
14596 try {
14597 int pid = Integer.parseInt(process);
14598 synchronized (mPidsSelfLocked) {
14599 proc = mPidsSelfLocked.get(pid);
14600 }
14601 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014602 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014603
14604 if (proc == null) {
14605 HashMap<String, SparseArray<ProcessRecord>> all
14606 = mProcessNames.getMap();
14607 SparseArray<ProcessRecord> procs = all.get(process);
14608 if (procs != null && procs.size() > 0) {
14609 proc = procs.valueAt(0);
14610 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014611 }
14612 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014613
14614 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014615 throw new IllegalArgumentException("Unknown process: " + process);
14616 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014617
14618 if (start) {
14619 stopProfilerLocked(null, null, 0);
14620 setProfileApp(proc.info, proc.processName, path, fd, false);
14621 mProfileProc = proc;
14622 mProfileType = profileType;
14623 try {
14624 fd = fd.dup();
14625 } catch (IOException e) {
14626 fd = null;
14627 }
14628 proc.thread.profilerControl(start, path, fd, profileType);
14629 fd = null;
14630 mProfileFd = null;
14631 } else {
14632 stopProfilerLocked(proc, path, profileType);
14633 if (fd != null) {
14634 try {
14635 fd.close();
14636 } catch (IOException e) {
14637 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014638 }
14639 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014640
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014641 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014642 }
14643 } catch (RemoteException e) {
14644 throw new IllegalStateException("Process disappeared");
14645 } finally {
14646 if (fd != null) {
14647 try {
14648 fd.close();
14649 } catch (IOException e) {
14650 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014651 }
14652 }
14653 }
Andy McFadden824c5102010-07-09 16:26:57 -070014654
14655 public boolean dumpHeap(String process, boolean managed,
14656 String path, ParcelFileDescriptor fd) throws RemoteException {
14657
14658 try {
14659 synchronized (this) {
14660 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14661 // its own permission (same as profileControl).
14662 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14663 != PackageManager.PERMISSION_GRANTED) {
14664 throw new SecurityException("Requires permission "
14665 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14666 }
14667
14668 if (fd == null) {
14669 throw new IllegalArgumentException("null fd");
14670 }
14671
14672 ProcessRecord proc = null;
14673 try {
14674 int pid = Integer.parseInt(process);
14675 synchronized (mPidsSelfLocked) {
14676 proc = mPidsSelfLocked.get(pid);
14677 }
14678 } catch (NumberFormatException e) {
14679 }
14680
14681 if (proc == null) {
14682 HashMap<String, SparseArray<ProcessRecord>> all
14683 = mProcessNames.getMap();
14684 SparseArray<ProcessRecord> procs = all.get(process);
14685 if (procs != null && procs.size() > 0) {
14686 proc = procs.valueAt(0);
14687 }
14688 }
14689
14690 if (proc == null || proc.thread == null) {
14691 throw new IllegalArgumentException("Unknown process: " + process);
14692 }
14693
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014694 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14695 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014696 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14697 throw new SecurityException("Process not debuggable: " + proc);
14698 }
14699 }
14700
14701 proc.thread.dumpHeap(managed, path, fd);
14702 fd = null;
14703 return true;
14704 }
14705 } catch (RemoteException e) {
14706 throw new IllegalStateException("Process disappeared");
14707 } finally {
14708 if (fd != null) {
14709 try {
14710 fd.close();
14711 } catch (IOException e) {
14712 }
14713 }
14714 }
14715 }
14716
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014717 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14718 public void monitor() {
14719 synchronized (this) { }
14720 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014721
14722 public void onCoreSettingsChange(Bundle settings) {
14723 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14724 ProcessRecord processRecord = mLruProcesses.get(i);
14725 try {
14726 if (processRecord.thread != null) {
14727 processRecord.thread.setCoreSettings(settings);
14728 }
14729 } catch (RemoteException re) {
14730 /* ignore */
14731 }
14732 }
14733 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014734
14735 // Multi-user methods
14736
14737 public boolean switchUser(int userid) {
14738 // TODO
14739 return true;
14740 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014741}