blob: db0a736dfefad83fe5cdd2b3a41084b5fbc58813 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Dianne Hackborn905577f2011-09-07 18:31:28 -0700109import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800111import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.util.PrintWriterPrinter;
113import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700114import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Gravity;
116import android.view.LayoutInflater;
117import android.view.View;
118import android.view.WindowManager;
119import android.view.WindowManagerPolicy;
120
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700121import java.io.BufferedInputStream;
122import java.io.BufferedOutputStream;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700123import java.io.BufferedReader;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700124import java.io.DataInputStream;
125import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126import java.io.File;
127import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700130import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200131import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800132import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133import java.io.PrintWriter;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700134import java.io.StringWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135import java.lang.IllegalStateException;
136import java.lang.ref.WeakReference;
137import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700138import java.util.Collections;
139import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140import java.util.HashMap;
141import java.util.HashSet;
142import java.util.Iterator;
143import java.util.List;
144import java.util.Locale;
145import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700146import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700147import java.util.concurrent.atomic.AtomicBoolean;
148import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700150public final class ActivityManagerService extends ActivityManagerNative
151 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final String TAG = "ActivityManager";
153 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400154 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 static final boolean DEBUG_SWITCH = localLOGV || false;
156 static final boolean DEBUG_TASKS = localLOGV || false;
157 static final boolean DEBUG_PAUSE = localLOGV || false;
158 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
159 static final boolean DEBUG_TRANSITION = localLOGV || false;
160 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700161 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700163 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 static final boolean DEBUG_VISBILITY = localLOGV || false;
165 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700166 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800167 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700169 static final boolean DEBUG_RESULTS = localLOGV || false;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -0700170 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700171 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700172 static final boolean DEBUG_POWER = localLOGV || false;
173 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 static final boolean VALIDATE_TOKENS = false;
175 static final boolean SHOW_ACTIVITY_START_TIME = true;
176
177 // Control over CPU and battery monitoring.
178 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
179 static final boolean MONITOR_CPU_USAGE = true;
180 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
181 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
182 static final boolean MONITOR_THREAD_CPU_USAGE = false;
183
Dianne Hackborn1655be42009-05-08 14:29:01 -0700184 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700185 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700186
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800187 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 // Maximum number of recent tasks that we can remember.
190 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700191
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700192 // Amount of time after a call to stopAppSwitches() during which we will
193 // prevent further untrusted switches from happening.
194 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195
196 // How long we wait for a launched process to attach to the activity manager
197 // before we decide it's never going to come up for real.
198 static final int PROC_START_TIMEOUT = 10*1000;
199
Jeff Brown3f9dd282011-07-08 20:02:19 -0700200 // How long we wait for a launched process to attach to the activity manager
201 // before we decide it's never going to come up for real, when the process was
202 // started with a wrapper for instrumentation (such as Valgrind) because it
203 // could take much longer than usual.
204 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 // How long to wait after going idle before forcing apps to GC.
207 static final int GC_TIMEOUT = 5*1000;
208
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700209 // The minimum amount of time between successive GC requests for a process.
210 static final int GC_MIN_INTERVAL = 60*1000;
211
Dianne Hackborn287952c2010-09-22 22:34:31 -0700212 // The rate at which we check for apps using excessive power -- 15 mins.
213 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
214
215 // The minimum sample duration we will allow before deciding we have
216 // enough data on wake locks to start killing things.
217 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
218
219 // The minimum sample duration we will allow before deciding we have
220 // enough data on CPU usage to start killing things.
221 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 // How long we allow a receiver to run before giving up on it.
224 static final int BROADCAST_TIMEOUT = 10*1000;
225
226 // How long we wait for a service to finish executing.
227 static final int SERVICE_TIMEOUT = 20*1000;
228
229 // How long a service needs to be running until restarting its process
230 // is no longer considered to be a relaunch of the service.
231 static final int SERVICE_RESTART_DURATION = 5*1000;
232
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700233 // How long a service needs to be running until it will start back at
234 // SERVICE_RESTART_DURATION after being killed.
235 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
236
237 // Multiplying factor to increase restart duration time by, for each time
238 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
239 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
240
241 // The minimum amount of time between restarting services that we allow.
242 // That is, when multiple services are restarting, we won't allow each
243 // to restart less than this amount of time from the last one.
244 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 // Maximum amount of time for there to be no activity on a service before
247 // we consider it non-essential and allow its process to go on the
248 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700249 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250
251 // How long we wait until we timeout on key dispatching.
252 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 // How long we wait until we timeout on key dispatching during instrumentation.
255 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
256
Dan Egnor42471dd2010-01-07 17:25:22 -0800257 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258
259 static final String[] EMPTY_STRING_ARRAY = new String[0];
260
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700261 public ActivityStack mMainStack;
262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700264 * Description of a request to start a new activity, which has been held
265 * due to app switches being disabled.
266 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700267 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700268 ActivityRecord r;
269 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700270 Uri[] grantedUriPermissions;
271 int grantedMode;
272 boolean onlyIfNeeded;
273 }
274
275 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
276 = new ArrayList<PendingActivityLaunch>();
277
278 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 * List of all active broadcasts that are to be executed immediately
280 * (without waiting for another broadcast to finish). Currently this only
281 * contains broadcasts to registered receivers, to avoid spinning up
282 * a bunch of processes to execute IntentReceiver components.
283 */
284 final ArrayList<BroadcastRecord> mParallelBroadcasts
285 = new ArrayList<BroadcastRecord>();
286
287 /**
288 * List of all active broadcasts that are to be executed one at a time.
289 * The object at the top of the list is the currently activity broadcasts;
290 * those after it are waiting for the top to finish..
291 */
292 final ArrayList<BroadcastRecord> mOrderedBroadcasts
293 = new ArrayList<BroadcastRecord>();
294
295 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800296 * Historical data of past broadcasts, for debugging.
297 */
Dianne Hackborn28695e02011-11-02 21:59:51 -0700298 static final int MAX_BROADCAST_HISTORY = 25;
Dianne Hackborn12527f92009-11-11 17:39:50 -0800299 final BroadcastRecord[] mBroadcastHistory
300 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
301
302 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 * Set when we current have a BROADCAST_INTENT_MSG in flight.
304 */
305 boolean mBroadcastsScheduled = false;
306
307 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 * Activity we have told the window manager to have key focus.
309 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700310 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700311 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 * List of intents that were used to start the most recent tasks.
313 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700314 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315
316 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700317 * Process management.
318 */
319 final ProcessList mProcessList = new ProcessList();
320
321 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 * All of the applications we currently have running organized by name.
323 * The keys are strings of the application package name (as
324 * returned by the package manager), and the keys are ApplicationRecord
325 * objects.
326 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700327 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328
329 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700330 * The currently running heavy-weight process, if any.
331 */
332 ProcessRecord mHeavyWeightProcess = null;
333
334 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 * The last time that various processes have crashed.
336 */
337 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
338
339 /**
340 * Set of applications that we consider to be bad, and will reject
341 * incoming broadcasts from (which the user has no control over).
342 * Processes are added to this set when they have crashed twice within
343 * a minimum amount of time; they are removed from it when they are
344 * later restarted (hopefully due to some user action). The value is the
345 * time it was added to the list.
346 */
347 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
348
349 /**
350 * All of the processes we currently have running organized by pid.
351 * The keys are the pid running the application.
352 *
353 * <p>NOTE: This object is protected by its own lock, NOT the global
354 * activity manager lock!
355 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700356 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357
358 /**
359 * All of the processes that have been forced to be foreground. The key
360 * is the pid of the caller who requested it (we hold a death
361 * link on it).
362 */
363 abstract class ForegroundToken implements IBinder.DeathRecipient {
364 int pid;
365 IBinder token;
366 }
367 final SparseArray<ForegroundToken> mForegroundProcesses
368 = new SparseArray<ForegroundToken>();
369
370 /**
371 * List of records for processes that someone had tried to start before the
372 * system was ready. We don't start them at that point, but ensure they
373 * are started by the time booting is complete.
374 */
375 final ArrayList<ProcessRecord> mProcessesOnHold
376 = new ArrayList<ProcessRecord>();
377
378 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 * List of persistent applications that are in the process
380 * of being started.
381 */
382 final ArrayList<ProcessRecord> mPersistentStartingProcesses
383 = new ArrayList<ProcessRecord>();
384
385 /**
386 * Processes that are being forcibly torn down.
387 */
388 final ArrayList<ProcessRecord> mRemovedProcesses
389 = new ArrayList<ProcessRecord>();
390
391 /**
392 * List of running applications, sorted by recent usage.
393 * The first entry in the list is the least recently used.
394 * It contains ApplicationRecord objects. This list does NOT include
395 * any persistent application records (since we never want to exit them).
396 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800397 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 = new ArrayList<ProcessRecord>();
399
400 /**
401 * List of processes that should gc as soon as things are idle.
402 */
403 final ArrayList<ProcessRecord> mProcessesToGc
404 = new ArrayList<ProcessRecord>();
405
406 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800407 * This is the process holding what we currently consider to be
408 * the "home" activity.
409 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700410 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800411
412 /**
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700413 * This is the process holding the activity the user last visited that
414 * is in a different process from the one they are currently in.
415 */
416 ProcessRecord mPreviousProcess;
Dianne Hackborn50685602011-12-01 12:23:37 -0800417
418 /**
419 * The time at which the previous process was last visible.
420 */
421 long mPreviousProcessVisibleTime;
422
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700423 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400424 * Packages that the user has asked to have run in screen size
425 * compatibility mode instead of filling the screen.
426 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700427 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400428
429 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 * Set of PendingResultRecord objects that are currently active.
431 */
432 final HashSet mPendingResultRecords = new HashSet();
433
434 /**
435 * Set of IntentSenderRecord objects that are currently active.
436 */
437 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
438 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
439
440 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800441 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700442 * already logged DropBox entries for. Guarded by itself. If
443 * something (rogue user app) forces this over
444 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
445 */
446 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
447 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
448
449 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700450 * Strict Mode background batched logging state.
451 *
452 * The string buffer is guarded by itself, and its lock is also
453 * used to determine if another batched write is already
454 * in-flight.
455 */
456 private final StringBuilder mStrictModeBuffer = new StringBuilder();
457
458 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700459 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
460 */
461 private boolean mPendingBroadcastTimeoutMessage;
462
463 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 * Intent broadcast that we have tried to start, but are
465 * waiting for its application's process to be created. We only
466 * need one (instead of a list) because we always process broadcasts
467 * one at a time, so no others can be started while waiting for this
468 * one.
469 */
470 BroadcastRecord mPendingBroadcast = null;
471
472 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700473 * The receiver index that is pending, to restart the broadcast if needed.
474 */
475 int mPendingBroadcastRecvIndex;
476
477 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 * Keeps track of all IIntentReceivers that have been registered for
479 * broadcasts. Hash keys are the receiver IBinder, hash value is
480 * a ReceiverList.
481 */
482 final HashMap mRegisteredReceivers = new HashMap();
483
484 /**
485 * Resolver for broadcast intents to registered receivers.
486 * Holds BroadcastFilter (subclass of IntentFilter).
487 */
488 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
489 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
490 @Override
491 protected boolean allowFilterResult(
492 BroadcastFilter filter, List<BroadcastFilter> dest) {
493 IBinder target = filter.receiverList.receiver.asBinder();
494 for (int i=dest.size()-1; i>=0; i--) {
495 if (dest.get(i).receiverList.receiver.asBinder() == target) {
496 return false;
497 }
498 }
499 return true;
500 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700501
502 @Override
503 protected String packageForFilter(BroadcastFilter filter) {
504 return filter.packageName;
505 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 };
507
508 /**
509 * State of all active sticky broadcasts. Keys are the action of the
510 * sticky Intent, values are an ArrayList of all broadcasted intents with
511 * that action (which should usually be one).
512 */
513 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
514 new HashMap<String, ArrayList<Intent>>();
515
516 /**
517 * All currently running services.
518 */
519 final HashMap<ComponentName, ServiceRecord> mServices =
520 new HashMap<ComponentName, ServiceRecord>();
521
522 /**
523 * All currently running services indexed by the Intent used to start them.
524 */
525 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
526 new HashMap<Intent.FilterComparison, ServiceRecord>();
527
528 /**
529 * All currently bound service connections. Keys are the IBinder of
530 * the client's IServiceConnection.
531 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700532 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
533 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534
535 /**
536 * List of services that we have been asked to start,
537 * but haven't yet been able to. It is used to hold start requests
538 * while waiting for their corresponding application thread to get
539 * going.
540 */
541 final ArrayList<ServiceRecord> mPendingServices
542 = new ArrayList<ServiceRecord>();
543
544 /**
545 * List of services that are scheduled to restart following a crash.
546 */
547 final ArrayList<ServiceRecord> mRestartingServices
548 = new ArrayList<ServiceRecord>();
549
550 /**
551 * List of services that are in the process of being stopped.
552 */
553 final ArrayList<ServiceRecord> mStoppingServices
554 = new ArrayList<ServiceRecord>();
555
556 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700557 * Backup/restore process management
558 */
559 String mBackupAppName = null;
560 BackupRecord mBackupTarget = null;
561
562 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 * List of PendingThumbnailsRecord objects of clients who are still
564 * waiting to receive all of the thumbnails for a task.
565 */
566 final ArrayList mPendingThumbnails = new ArrayList();
567
568 /**
569 * List of HistoryRecord objects that have been finished and must
570 * still report back to a pending thumbnail receiver.
571 */
572 final ArrayList mCancelledThumbnails = new ArrayList();
573
574 /**
575 * All of the currently running global content providers. Keys are a
576 * string containing the provider name and values are a
577 * ContentProviderRecord object containing the data about it. Note
578 * that a single provider may be published under multiple names, so
579 * there may be multiple entries here for a single one in mProvidersByClass.
580 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700581 final HashMap<String, ContentProviderRecord> mProvidersByName
582 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583
584 /**
585 * All of the currently running global content providers. Keys are a
586 * string containing the provider's implementation class and values are a
587 * ContentProviderRecord object containing the data about it.
588 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700589 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
590 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591
592 /**
593 * List of content providers who have clients waiting for them. The
594 * application is currently being launched and the provider will be
595 * removed from this list once it is published.
596 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700597 final ArrayList<ContentProviderRecord> mLaunchingProviders
598 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599
600 /**
601 * Global set of specific Uri permissions that have been granted.
602 */
603 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
604 = new SparseArray<HashMap<Uri, UriPermission>>();
605
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800606 CoreSettingsObserver mCoreSettingsObserver;
607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 /**
609 * Thread-local storage used to carry caller permissions over through
610 * indirect content-provider access.
611 * @see #ActivityManagerService.openContentUri()
612 */
613 private class Identity {
614 public int pid;
615 public int uid;
616
617 Identity(int _pid, int _uid) {
618 pid = _pid;
619 uid = _uid;
620 }
621 }
622 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
623
624 /**
625 * All information we have collected about the runtime performance of
626 * any user id that can impact battery performance.
627 */
628 final BatteryStatsService mBatteryStatsService;
629
630 /**
631 * information about component usage
632 */
633 final UsageStatsService mUsageStatsService;
634
635 /**
636 * Current configuration information. HistoryRecord objects are given
637 * a reference to this object to indicate which configuration they are
638 * currently running in, so this object must be kept immutable.
639 */
640 Configuration mConfiguration = new Configuration();
641
642 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800643 * Current sequencing integer of the configuration, for skipping old
644 * configurations.
645 */
646 int mConfigurationSeq = 0;
647
648 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700649 * Hardware-reported OpenGLES version.
650 */
651 final int GL_ES_VERSION;
652
653 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 * List of initialization arguments to pass to all processes when binding applications to them.
655 * For example, references to the commonly used services.
656 */
657 HashMap<String, IBinder> mAppBindArgs;
658
659 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700660 * Temporary to avoid allocations. Protected by main lock.
661 */
662 final StringBuilder mStringBuilder = new StringBuilder(256);
663
664 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 * Used to control how we initialize the service.
666 */
667 boolean mStartRunning = false;
668 ComponentName mTopComponent;
669 String mTopAction;
670 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700671 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 boolean mSystemReady = false;
673 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700674 boolean mWaitingUpdate = false;
675 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700676 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700677 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678
679 Context mContext;
680
681 int mFactoryTest;
682
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700683 boolean mCheckedForSetup;
684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700686 * The time at which we will allow normal application switches again,
687 * after a call to {@link #stopAppSwitches()}.
688 */
689 long mAppSwitchesAllowedTime;
690
691 /**
692 * This is set to true after the first switch after mAppSwitchesAllowedTime
693 * is set; any switches after that will clear the time.
694 */
695 boolean mDidAppSwitch;
696
697 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700698 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700699 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700700 long mLastPowerCheckRealtime;
701
702 /**
703 * Last time (in uptime) at which we checked for power usage.
704 */
705 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700706
707 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 * Set while we are wanting to sleep, to prevent any
709 * activities from being started/resumed.
710 */
711 boolean mSleeping = false;
712
713 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700714 * Set if we are shutting down the system, similar to sleeping.
715 */
716 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717
718 /**
719 * Task identifier that activities are currently being started
720 * in. Incremented each time a new task is created.
721 * todo: Replace this with a TokenSpace class that generates non-repeating
722 * integers that won't wrap.
723 */
724 int mCurTask = 1;
725
726 /**
727 * Current sequence id for oom_adj computation traversal.
728 */
729 int mAdjSeq = 0;
730
731 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700732 * Current sequence id for process LRU updating.
733 */
734 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735
736 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700737 * Keep track of the number of service processes we last found, to
738 * determine on the next iteration which should be B services.
739 */
740 int mNumServiceProcs = 0;
741 int mNewNumServiceProcs = 0;
742
743 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 * System monitoring: number of processes that died since the last
745 * N procs were started.
746 */
747 int[] mProcDeaths = new int[20];
748
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700749 /**
750 * This is set if we had to do a delayed dexopt of an app before launching
751 * it, to increasing the ANR timeouts in that case.
752 */
753 boolean mDidDexOpt;
754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 String mDebugApp = null;
756 boolean mWaitForDebugger = false;
757 boolean mDebugTransient = false;
758 String mOrigDebugApp = null;
759 boolean mOrigWaitForDebugger = false;
760 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700761 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700762 String mProfileApp = null;
763 ProcessRecord mProfileProc = null;
764 String mProfileFile;
765 ParcelFileDescriptor mProfileFd;
766 int mProfileType = 0;
767 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700769 final RemoteCallbackList<IActivityWatcher> mWatchers
770 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700771
772 final RemoteCallbackList<IProcessObserver> mProcessObservers
773 = new RemoteCallbackList<IProcessObserver>();
774
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 /**
776 * Callback of last caller to {@link #requestPss}.
777 */
778 Runnable mRequestPssCallback;
779
780 /**
781 * Remaining processes for which we are waiting results from the last
782 * call to {@link #requestPss}.
783 */
784 final ArrayList<ProcessRecord> mRequestPssList
785 = new ArrayList<ProcessRecord>();
786
787 /**
788 * Runtime statistics collection thread. This object's lock is used to
789 * protect all related state.
790 */
791 final Thread mProcessStatsThread;
792
793 /**
794 * Used to collect process stats when showing not responding dialog.
795 * Protected by mProcessStatsThread.
796 */
797 final ProcessStats mProcessStats = new ProcessStats(
798 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700799 final AtomicLong mLastCpuTime = new AtomicLong(0);
800 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 long mLastWriteTime = 0;
803
804 /**
805 * Set to true after the system has finished booting.
806 */
807 boolean mBooted = false;
808
Dianne Hackborn7d608422011-08-07 16:24:18 -0700809 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700810 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811
812 WindowManagerService mWindowManager;
813
814 static ActivityManagerService mSelf;
815 static ActivityThread mSystemThread;
816
817 private final class AppDeathRecipient implements IBinder.DeathRecipient {
818 final ProcessRecord mApp;
819 final int mPid;
820 final IApplicationThread mAppThread;
821
822 AppDeathRecipient(ProcessRecord app, int pid,
823 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800824 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 TAG, "New death recipient " + this
826 + " for thread " + thread.asBinder());
827 mApp = app;
828 mPid = pid;
829 mAppThread = thread;
830 }
831
832 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800833 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 TAG, "Death received in " + this
835 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 synchronized(ActivityManagerService.this) {
837 appDiedLocked(mApp, mPid, mAppThread);
838 }
839 }
840 }
841
842 static final int SHOW_ERROR_MSG = 1;
843 static final int SHOW_NOT_RESPONDING_MSG = 2;
844 static final int SHOW_FACTORY_ERROR_MSG = 3;
845 static final int UPDATE_CONFIGURATION_MSG = 4;
846 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
847 static final int WAIT_FOR_DEBUGGER_MSG = 6;
848 static final int BROADCAST_INTENT_MSG = 7;
849 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 static final int SERVICE_TIMEOUT_MSG = 12;
851 static final int UPDATE_TIME_ZONE = 13;
852 static final int SHOW_UID_ERROR_MSG = 14;
853 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700855 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700856 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800857 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700858 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
859 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700860 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700861 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700862 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700863 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700864 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700865 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
866 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700867 static final int REPORT_MEM_USAGE = 33;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868
869 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700870 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700871 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872
873 final Handler mHandler = new Handler() {
874 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800875 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 //}
877
878 public void handleMessage(Message msg) {
879 switch (msg.what) {
880 case SHOW_ERROR_MSG: {
881 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 synchronized (ActivityManagerService.this) {
883 ProcessRecord proc = (ProcessRecord)data.get("app");
884 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800885 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 return;
887 }
888 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700889 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800890 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 d.show();
892 proc.crashDialog = d;
893 } else {
894 // The device is asleep, so just pretend that the user
895 // saw a crash dialog and hit "force quit".
896 res.set(0);
897 }
898 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700899
900 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800901 } break;
902 case SHOW_NOT_RESPONDING_MSG: {
903 synchronized (ActivityManagerService.this) {
904 HashMap data = (HashMap) msg.obj;
905 ProcessRecord proc = (ProcessRecord)data.get("app");
906 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800907 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 return;
909 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800910
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700911 Intent intent = new Intent("android.intent.action.ANR");
912 if (!mProcessesReady) {
913 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
914 }
915 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800916 null, null, 0, null, null, null,
917 false, false, MY_PID, Process.SYSTEM_UID);
918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700920 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 d.show();
922 proc.anrDialog = d;
923 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700924
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700925 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700927 case SHOW_STRICT_MODE_VIOLATION_MSG: {
928 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
929 synchronized (ActivityManagerService.this) {
930 ProcessRecord proc = (ProcessRecord) data.get("app");
931 if (proc == null) {
932 Slog.e(TAG, "App not found when showing strict mode dialog.");
933 break;
934 }
935 if (proc.crashDialog != null) {
936 Slog.e(TAG, "App already has strict mode dialog: " + proc);
937 return;
938 }
939 AppErrorResult res = (AppErrorResult) data.get("result");
940 if (!mSleeping && !mShuttingDown) {
941 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
942 d.show();
943 proc.crashDialog = d;
944 } else {
945 // The device is asleep, so just pretend that the user
946 // saw a crash dialog and hit "force quit".
947 res.set(0);
948 }
949 }
950 ensureBootCompleted();
951 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 case SHOW_FACTORY_ERROR_MSG: {
953 Dialog d = new FactoryErrorDialog(
954 mContext, msg.getData().getCharSequence("msg"));
955 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700956 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 } break;
958 case UPDATE_CONFIGURATION_MSG: {
959 final ContentResolver resolver = mContext.getContentResolver();
960 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
961 } break;
962 case GC_BACKGROUND_PROCESSES_MSG: {
963 synchronized (ActivityManagerService.this) {
964 performAppGcsIfAppropriateLocked();
965 }
966 } break;
967 case WAIT_FOR_DEBUGGER_MSG: {
968 synchronized (ActivityManagerService.this) {
969 ProcessRecord app = (ProcessRecord)msg.obj;
970 if (msg.arg1 != 0) {
971 if (!app.waitedForDebugger) {
972 Dialog d = new AppWaitingForDebuggerDialog(
973 ActivityManagerService.this,
974 mContext, app);
975 app.waitDialog = d;
976 app.waitedForDebugger = true;
977 d.show();
978 }
979 } else {
980 if (app.waitDialog != null) {
981 app.waitDialog.dismiss();
982 app.waitDialog = null;
983 }
984 }
985 }
986 } break;
987 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800988 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 TAG, "Received BROADCAST_INTENT_MSG");
990 processNextBroadcast(true);
991 } break;
992 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700993 synchronized (ActivityManagerService.this) {
994 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800997 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700998 if (mDidDexOpt) {
999 mDidDexOpt = false;
1000 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1001 nmsg.obj = msg.obj;
1002 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1003 return;
1004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 serviceTimeout((ProcessRecord)msg.obj);
1006 } break;
1007 case UPDATE_TIME_ZONE: {
1008 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001009 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1010 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 if (r.thread != null) {
1012 try {
1013 r.thread.updateTimeZone();
1014 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001015 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 }
1017 }
1018 }
1019 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001020 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001021 case CLEAR_DNS_CACHE: {
1022 synchronized (ActivityManagerService.this) {
1023 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1024 ProcessRecord r = mLruProcesses.get(i);
1025 if (r.thread != null) {
1026 try {
1027 r.thread.clearDnsCache();
1028 } catch (RemoteException ex) {
1029 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1030 }
1031 }
1032 }
1033 }
1034 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001035 case UPDATE_HTTP_PROXY: {
1036 ProxyProperties proxy = (ProxyProperties)msg.obj;
1037 String host = "";
1038 String port = "";
1039 String exclList = "";
1040 if (proxy != null) {
1041 host = proxy.getHost();
1042 port = Integer.toString(proxy.getPort());
1043 exclList = proxy.getExclusionList();
1044 }
1045 synchronized (ActivityManagerService.this) {
1046 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1047 ProcessRecord r = mLruProcesses.get(i);
1048 if (r.thread != null) {
1049 try {
1050 r.thread.setHttpProxy(host, port, exclList);
1051 } catch (RemoteException ex) {
1052 Slog.w(TAG, "Failed to update http proxy for: " +
1053 r.info.processName);
1054 }
1055 }
1056 }
1057 }
1058 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001059 case SHOW_UID_ERROR_MSG: {
1060 // XXX This is a temporary dialog, no need to localize.
1061 AlertDialog d = new BaseErrorDialog(mContext);
1062 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1063 d.setCancelable(false);
1064 d.setTitle("System UIDs Inconsistent");
1065 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
Christian Mehlmauer7664e202010-07-20 08:46:17 +02001066 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1068 mUidAlert = d;
1069 d.show();
1070 } break;
1071 case IM_FEELING_LUCKY_MSG: {
1072 if (mUidAlert != null) {
1073 mUidAlert.dismiss();
1074 mUidAlert = null;
1075 }
1076 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001078 if (mDidDexOpt) {
1079 mDidDexOpt = false;
1080 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1081 nmsg.obj = msg.obj;
1082 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1083 return;
1084 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 ProcessRecord app = (ProcessRecord)msg.obj;
1086 synchronized (ActivityManagerService.this) {
1087 processStartTimedOutLocked(app);
1088 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001089 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001090 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1091 synchronized (ActivityManagerService.this) {
1092 doPendingActivityLaunchesLocked(true);
1093 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001094 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001095 case KILL_APPLICATION_MSG: {
1096 synchronized (ActivityManagerService.this) {
1097 int uid = msg.arg1;
1098 boolean restart = (msg.arg2 == 1);
1099 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001100 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001101 }
1102 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001103 case FINALIZE_PENDING_INTENT_MSG: {
1104 ((PendingIntentRecord)msg.obj).completeFinalize();
1105 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001106 case POST_HEAVY_NOTIFICATION_MSG: {
1107 INotificationManager inm = NotificationManager.getService();
1108 if (inm == null) {
1109 return;
1110 }
1111
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001112 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001113 ProcessRecord process = root.app;
1114 if (process == null) {
1115 return;
1116 }
1117
1118 try {
1119 Context context = mContext.createPackageContext(process.info.packageName, 0);
1120 String text = mContext.getString(R.string.heavy_weight_notification,
1121 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1122 Notification notification = new Notification();
1123 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1124 notification.when = 0;
1125 notification.flags = Notification.FLAG_ONGOING_EVENT;
1126 notification.tickerText = text;
1127 notification.defaults = 0; // please be quiet
1128 notification.sound = null;
1129 notification.vibrate = null;
1130 notification.setLatestEventInfo(context, text,
1131 mContext.getText(R.string.heavy_weight_notification_detail),
1132 PendingIntent.getActivity(mContext, 0, root.intent,
1133 PendingIntent.FLAG_CANCEL_CURRENT));
1134
1135 try {
1136 int[] outId = new int[1];
1137 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1138 notification, outId);
1139 } catch (RuntimeException e) {
1140 Slog.w(ActivityManagerService.TAG,
1141 "Error showing notification for heavy-weight app", e);
1142 } catch (RemoteException e) {
1143 }
1144 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001145 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001146 }
1147 } break;
1148 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1149 INotificationManager inm = NotificationManager.getService();
1150 if (inm == null) {
1151 return;
1152 }
1153 try {
1154 inm.cancelNotification("android",
1155 R.string.heavy_weight_notification);
1156 } catch (RuntimeException e) {
1157 Slog.w(ActivityManagerService.TAG,
1158 "Error canceling notification for service", e);
1159 } catch (RemoteException e) {
1160 }
1161 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001162 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1163 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001164 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001165 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001166 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1167 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001168 }
1169 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001170 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1171 synchronized (ActivityManagerService.this) {
1172 ActivityRecord ar = (ActivityRecord)msg.obj;
1173 if (mCompatModeDialog != null) {
1174 if (mCompatModeDialog.mAppInfo.packageName.equals(
1175 ar.info.applicationInfo.packageName)) {
1176 return;
1177 }
1178 mCompatModeDialog.dismiss();
1179 mCompatModeDialog = null;
1180 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001181 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001182 if (mCompatModePackages.getPackageAskCompatModeLocked(
1183 ar.packageName)) {
1184 int mode = mCompatModePackages.computeCompatModeLocked(
1185 ar.info.applicationInfo);
1186 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1187 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1188 mCompatModeDialog = new CompatModeDialog(
1189 ActivityManagerService.this, mContext,
1190 ar.info.applicationInfo);
1191 mCompatModeDialog.show();
1192 }
1193 }
1194 }
1195 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001196 break;
1197 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001198 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001199 final int pid = msg.arg1;
1200 final int uid = msg.arg2;
1201 final boolean foregroundActivities = (Boolean) msg.obj;
1202 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001203 break;
1204 }
1205 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001206 final int pid = msg.arg1;
1207 final int uid = msg.arg2;
1208 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001209 break;
1210 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001211 case REPORT_MEM_USAGE: {
1212 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1213 if (!isDebuggable) {
1214 return;
1215 }
1216 synchronized (ActivityManagerService.this) {
1217 long now = SystemClock.uptimeMillis();
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001218 if (now < (mLastMemUsageReportTime+5*60*1000)) {
1219 // Don't report more than every 5 minutes to somewhat
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001220 // avoid spamming.
1221 return;
1222 }
1223 mLastMemUsageReportTime = now;
1224 }
1225 Thread thread = new Thread() {
1226 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001227 StringBuilder dropBuilder = new StringBuilder(1024);
1228 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08001229 StringWriter oomSw = new StringWriter();
1230 PrintWriter oomPw = new PrintWriter(oomSw);
1231 StringWriter catSw = new StringWriter();
1232 PrintWriter catPw = new PrintWriter(catSw);
1233 String[] emptyArgs = new String[] { };
1234 StringBuilder tag = new StringBuilder(128);
1235 StringBuilder stack = new StringBuilder(128);
1236 tag.append("Low on memory -- ");
1237 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw,
1238 tag, stack);
1239 dropBuilder.append(stack);
1240 dropBuilder.append('\n');
1241 dropBuilder.append('\n');
1242 String oomString = oomSw.toString();
1243 dropBuilder.append(oomString);
1244 dropBuilder.append('\n');
1245 logBuilder.append(oomString);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001246 try {
1247 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1248 "procrank", });
1249 final InputStreamReader converter = new InputStreamReader(
1250 proc.getInputStream());
1251 BufferedReader in = new BufferedReader(converter);
1252 String line;
1253 while (true) {
1254 line = in.readLine();
1255 if (line == null) {
1256 break;
1257 }
1258 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001259 logBuilder.append(line);
1260 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001261 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001262 dropBuilder.append(line);
1263 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001264 }
1265 converter.close();
1266 } catch (IOException e) {
1267 }
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001268 synchronized (ActivityManagerService.this) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08001269 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001270 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001271 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001272 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001273 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001274 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001275 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001276 dropBuilder.append(catSw.toString());
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001277 addErrorToDropBox("lowmem", null, "system_server", null,
1278 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001279 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001280 synchronized (ActivityManagerService.this) {
1281 long now = SystemClock.uptimeMillis();
1282 if (mLastMemUsageReportTime < now) {
1283 mLastMemUsageReportTime = now;
1284 }
1285 }
1286 }
1287 };
1288 thread.start();
1289 break;
1290 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001291 }
1292 }
1293 };
1294
1295 public static void setSystemProcess() {
1296 try {
1297 ActivityManagerService m = mSelf;
1298
1299 ServiceManager.addService("activity", m);
1300 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001301 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
Jeff Brown6754ba22011-12-14 20:20:01 -08001302 ServiceManager.addService("dbinfo", new DbBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 if (MONITOR_CPU_USAGE) {
1304 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 ServiceManager.addService("permission", new PermissionController(m));
1307
1308 ApplicationInfo info =
1309 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001310 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001311 mSystemThread.installSystemApplicationInfo(info);
1312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 synchronized (mSelf) {
1314 ProcessRecord app = mSelf.newProcessRecordLocked(
1315 mSystemThread.getApplicationThread(), info,
1316 info.processName);
1317 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001318 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001319 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1321 synchronized (mSelf.mPidsSelfLocked) {
1322 mSelf.mPidsSelfLocked.put(app.pid, app);
1323 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001324 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 }
1326 } catch (PackageManager.NameNotFoundException e) {
1327 throw new RuntimeException(
1328 "Unable to find android system package", e);
1329 }
1330 }
1331
1332 public void setWindowManager(WindowManagerService wm) {
1333 mWindowManager = wm;
1334 }
1335
1336 public static final Context main(int factoryTest) {
1337 AThread thr = new AThread();
1338 thr.start();
1339
1340 synchronized (thr) {
1341 while (thr.mService == null) {
1342 try {
1343 thr.wait();
1344 } catch (InterruptedException e) {
1345 }
1346 }
1347 }
1348
1349 ActivityManagerService m = thr.mService;
1350 mSelf = m;
1351 ActivityThread at = ActivityThread.systemMain();
1352 mSystemThread = at;
1353 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001354 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 m.mContext = context;
1356 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001357 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358
1359 m.mBatteryStatsService.publish(context);
1360 m.mUsageStatsService.publish(context);
1361
1362 synchronized (thr) {
1363 thr.mReady = true;
1364 thr.notifyAll();
1365 }
1366
1367 m.startRunning(null, null, null, null);
1368
1369 return context;
1370 }
1371
1372 public static ActivityManagerService self() {
1373 return mSelf;
1374 }
1375
1376 static class AThread extends Thread {
1377 ActivityManagerService mService;
1378 boolean mReady = false;
1379
1380 public AThread() {
1381 super("ActivityManager");
1382 }
1383
1384 public void run() {
1385 Looper.prepare();
1386
1387 android.os.Process.setThreadPriority(
1388 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001389 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390
1391 ActivityManagerService m = new ActivityManagerService();
1392
1393 synchronized (this) {
1394 mService = m;
1395 notifyAll();
1396 }
1397
1398 synchronized (this) {
1399 while (!mReady) {
1400 try {
1401 wait();
1402 } catch (InterruptedException e) {
1403 }
1404 }
1405 }
1406
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001407 // For debug builds, log event loop stalls to dropbox for analysis.
1408 if (StrictMode.conditionallyEnableDebugLogging()) {
1409 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1410 }
1411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 Looper.loop();
1413 }
1414 }
1415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 static class MemBinder extends Binder {
1417 ActivityManagerService mActivityManagerService;
1418 MemBinder(ActivityManagerService activityManagerService) {
1419 mActivityManagerService = activityManagerService;
1420 }
1421
1422 @Override
1423 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001424 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1425 != PackageManager.PERMISSION_GRANTED) {
1426 pw.println("Permission Denial: can't dump meminfo from from pid="
1427 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1428 + " without permission " + android.Manifest.permission.DUMP);
1429 return;
1430 }
1431
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001432 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
Dianne Hackborn672342c2011-11-29 11:29:02 -08001433 false, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 }
1435 }
1436
Chet Haase9c1e23b2011-03-24 10:51:31 -07001437 static class GraphicsBinder extends Binder {
1438 ActivityManagerService mActivityManagerService;
1439 GraphicsBinder(ActivityManagerService activityManagerService) {
1440 mActivityManagerService = activityManagerService;
1441 }
1442
1443 @Override
1444 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001445 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1446 != PackageManager.PERMISSION_GRANTED) {
1447 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1448 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1449 + " without permission " + android.Manifest.permission.DUMP);
1450 return;
1451 }
1452
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001453 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001454 }
1455 }
1456
Jeff Brown6754ba22011-12-14 20:20:01 -08001457 static class DbBinder extends Binder {
1458 ActivityManagerService mActivityManagerService;
1459 DbBinder(ActivityManagerService activityManagerService) {
1460 mActivityManagerService = activityManagerService;
1461 }
1462
1463 @Override
1464 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1465 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1466 != PackageManager.PERMISSION_GRANTED) {
1467 pw.println("Permission Denial: can't dump dbinfo from from pid="
1468 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1469 + " without permission " + android.Manifest.permission.DUMP);
1470 return;
1471 }
1472
1473 mActivityManagerService.dumpDbInfo(fd, pw, args);
1474 }
1475 }
1476
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 static class CpuBinder extends Binder {
1478 ActivityManagerService mActivityManagerService;
1479 CpuBinder(ActivityManagerService activityManagerService) {
1480 mActivityManagerService = activityManagerService;
1481 }
1482
1483 @Override
1484 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001485 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1486 != PackageManager.PERMISSION_GRANTED) {
1487 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1488 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1489 + " without permission " + android.Manifest.permission.DUMP);
1490 return;
1491 }
1492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001494 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1495 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1496 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 }
1498 }
1499 }
1500
1501 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001502 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 File dataDir = Environment.getDataDirectory();
1505 File systemDir = new File(dataDir, "system");
1506 systemDir.mkdirs();
1507 mBatteryStatsService = new BatteryStatsService(new File(
1508 systemDir, "batterystats.bin").toString());
1509 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001510 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001511 mOnBattery = DEBUG_POWER ? true
1512 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001513 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001515 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001516 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517
Jack Palevichb90d28c2009-07-22 15:35:24 -07001518 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1519 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1520
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001521 mConfiguration.setToDefaults();
1522 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08001523 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001524 mProcessStats.init();
1525
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001526 mCompatModePackages = new CompatModePackages(this, systemDir);
1527
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 // Add ourself to the Watchdog monitors.
1529 Watchdog.getInstance().addMonitor(this);
1530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 mProcessStatsThread = new Thread("ProcessStats") {
1532 public void run() {
1533 while (true) {
1534 try {
1535 try {
1536 synchronized(this) {
1537 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001538 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001540 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 // + ", write delay=" + nextWriteDelay);
1542 if (nextWriteDelay < nextCpuDelay) {
1543 nextCpuDelay = nextWriteDelay;
1544 }
1545 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001546 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001547 this.wait(nextCpuDelay);
1548 }
1549 }
1550 } catch (InterruptedException e) {
1551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 updateCpuStatsNow();
1553 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001554 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 }
1556 }
1557 }
1558 };
1559 mProcessStatsThread.start();
1560 }
1561
1562 @Override
1563 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1564 throws RemoteException {
1565 try {
1566 return super.onTransact(code, data, reply, flags);
1567 } catch (RuntimeException e) {
1568 // The activity manager only throws security exceptions, so let's
1569 // log all others.
1570 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001571 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 }
1573 throw e;
1574 }
1575 }
1576
1577 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001578 final long now = SystemClock.uptimeMillis();
1579 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1580 return;
1581 }
1582 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1583 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 mProcessStatsThread.notify();
1585 }
1586 }
1587 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 void updateCpuStatsNow() {
1590 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001591 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 final long now = SystemClock.uptimeMillis();
1593 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001596 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1597 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001598 haveNewCpuStats = true;
1599 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001600 //Slog.i(TAG, mProcessStats.printCurrentState());
1601 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001602 // + mProcessStats.getTotalCpuPercent() + "%");
1603
Joe Onorato8a9b2202010-02-26 18:56:32 -08001604 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001605 if ("true".equals(SystemProperties.get("events.cpu"))) {
1606 int user = mProcessStats.getLastUserTime();
1607 int system = mProcessStats.getLastSystemTime();
1608 int iowait = mProcessStats.getLastIoWaitTime();
1609 int irq = mProcessStats.getLastIrqTime();
1610 int softIrq = mProcessStats.getLastSoftIrqTime();
1611 int idle = mProcessStats.getLastIdleTime();
1612
1613 int total = user + system + iowait + irq + softIrq + idle;
1614 if (total == 0) total = 1;
1615
Doug Zongker2bec3d42009-12-04 12:52:44 -08001616 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001617 ((user+system+iowait+irq+softIrq) * 100) / total,
1618 (user * 100) / total,
1619 (system * 100) / total,
1620 (iowait * 100) / total,
1621 (irq * 100) / total,
1622 (softIrq * 100) / total);
1623 }
1624 }
1625
Amith Yamasanie43530a2009-08-21 13:11:37 -07001626 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001627 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001628 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001629 synchronized(mPidsSelfLocked) {
1630 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001631 if (mOnBattery) {
1632 int perc = bstats.startAddingCpuLocked();
1633 int totalUTime = 0;
1634 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001635 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001636 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001637 ProcessStats.Stats st = mProcessStats.getStats(i);
1638 if (!st.working) {
1639 continue;
1640 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001641 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001642 int otherUTime = (st.rel_utime*perc)/100;
1643 int otherSTime = (st.rel_stime*perc)/100;
1644 totalUTime += otherUTime;
1645 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001646 if (pr != null) {
1647 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001648 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1649 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001650 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001651 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001652 } else {
1653 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001654 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001655 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001656 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1657 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001658 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001659 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001660 }
1661 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001662 bstats.finishAddingCpuLocked(perc, totalUTime,
1663 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001664 }
1665 }
1666 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001668 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1669 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001670 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001671 }
1672 }
1673 }
1674 }
1675
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001676 @Override
1677 public void batteryNeedsCpuUpdate() {
1678 updateCpuStatsNow();
1679 }
1680
1681 @Override
1682 public void batteryPowerChanged(boolean onBattery) {
1683 // When plugging in, update the CPU stats first before changing
1684 // the plug state.
1685 updateCpuStatsNow();
1686 synchronized (this) {
1687 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001688 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001689 }
1690 }
1691 }
1692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001693 /**
1694 * Initialize the application bind args. These are passed to each
1695 * process when the bindApplication() IPC is sent to the process. They're
1696 * lazily setup to make sure the services are running when they're asked for.
1697 */
1698 private HashMap<String, IBinder> getCommonServicesLocked() {
1699 if (mAppBindArgs == null) {
1700 mAppBindArgs = new HashMap<String, IBinder>();
1701
1702 // Setup the application init args
1703 mAppBindArgs.put("package", ServiceManager.getService("package"));
1704 mAppBindArgs.put("window", ServiceManager.getService("window"));
1705 mAppBindArgs.put(Context.ALARM_SERVICE,
1706 ServiceManager.getService(Context.ALARM_SERVICE));
1707 }
1708 return mAppBindArgs;
1709 }
1710
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001711 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001712 if (mFocusedActivity != r) {
1713 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001714 if (r != null) {
1715 mWindowManager.setFocusedApp(r.appToken, true);
1716 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001717 }
1718 }
1719
Dianne Hackborn906497c2010-05-10 15:57:38 -07001720 private final void updateLruProcessInternalLocked(ProcessRecord app,
1721 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001723 int lrui = mLruProcesses.indexOf(app);
1724 if (lrui >= 0) mLruProcesses.remove(lrui);
1725
1726 int i = mLruProcesses.size()-1;
1727 int skipTop = 0;
1728
Dianne Hackborn906497c2010-05-10 15:57:38 -07001729 app.lruSeq = mLruSeq;
1730
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001731 // compute the new weight for this process.
1732 if (updateActivityTime) {
1733 app.lastActivityTime = SystemClock.uptimeMillis();
1734 }
1735 if (app.activities.size() > 0) {
1736 // If this process has activities, we more strongly want to keep
1737 // it around.
1738 app.lruWeight = app.lastActivityTime;
1739 } else if (app.pubProviders.size() > 0) {
1740 // If this process contains content providers, we want to keep
1741 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001742 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001743 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001744 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001745 } else {
1746 // If this process doesn't have activities, we less strongly
1747 // want to keep it around, and generally want to avoid getting
1748 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001749 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001750 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001751 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001752 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001753
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001754 while (i >= 0) {
1755 ProcessRecord p = mLruProcesses.get(i);
1756 // If this app shouldn't be in front of the first N background
1757 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001758 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001759 skipTop--;
1760 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001761 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001762 mLruProcesses.add(i+1, app);
1763 break;
1764 }
1765 i--;
1766 }
1767 if (i < 0) {
1768 mLruProcesses.add(0, app);
1769 }
1770
Dianne Hackborn906497c2010-05-10 15:57:38 -07001771 // If the app is currently using a content provider or service,
1772 // bump those processes as well.
1773 if (app.connections.size() > 0) {
1774 for (ConnectionRecord cr : app.connections) {
1775 if (cr.binding != null && cr.binding.service != null
1776 && cr.binding.service.app != null
1777 && cr.binding.service.app.lruSeq != mLruSeq) {
1778 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1779 updateActivityTime, i+1);
1780 }
1781 }
1782 }
1783 if (app.conProviders.size() > 0) {
1784 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001785 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1786 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001787 updateActivityTime, i+1);
1788 }
1789 }
1790 }
1791
Joe Onorato8a9b2202010-02-26 18:56:32 -08001792 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001793 if (oomAdj) {
1794 updateOomAdjLocked();
1795 }
1796 }
1797
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001798 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001799 boolean oomAdj, boolean updateActivityTime) {
1800 mLruSeq++;
1801 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1802 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001803
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001804 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001805 String processName, int uid) {
1806 if (uid == Process.SYSTEM_UID) {
1807 // The system gets to run in any process. If there are multiple
1808 // processes with the same uid, just pick the first (this
1809 // should never happen).
1810 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1811 processName);
1812 return procs != null ? procs.valueAt(0) : null;
1813 }
1814 ProcessRecord proc = mProcessNames.get(processName, uid);
1815 return proc;
1816 }
1817
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001818 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001819 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001820 try {
1821 if (pm.performDexOpt(packageName)) {
1822 mDidDexOpt = true;
1823 }
1824 } catch (RemoteException e) {
1825 }
1826 }
1827
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001828 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 int transit = mWindowManager.getPendingAppTransition();
1830 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1831 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1832 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1833 }
1834
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001835 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001836 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001837 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001838 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1839 // We don't have to do anything more if:
1840 // (1) There is an existing application record; and
1841 // (2) The caller doesn't think it is dead, OR there is no thread
1842 // object attached to it so we know it couldn't have crashed; and
1843 // (3) There is a pid assigned to it, so it is either starting or
1844 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001845 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 + " app=" + app + " knownToBeDead=" + knownToBeDead
1847 + " thread=" + (app != null ? app.thread : null)
1848 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001849 if (app != null && app.pid > 0) {
1850 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001851 // We already have the app running, or are waiting for it to
1852 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001853 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001854 // If this is a new package in the process, add the package to the list
1855 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001856 return app;
1857 } else {
1858 // An application record is attached to a previous process,
1859 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001860 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001861 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001863 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865 String hostingNameStr = hostingName != null
1866 ? hostingName.flattenToShortString() : null;
1867
1868 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1869 // If we are in the background, then check to see if this process
1870 // is bad. If so, we will just silently fail.
1871 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001872 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1873 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001874 return null;
1875 }
1876 } else {
1877 // When the user is explicitly starting a process, then clear its
1878 // crash count so that we won't make it bad until they see at
1879 // least one crash dialog again, and make the process good again
1880 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001881 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1882 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001883 mProcessCrashTimes.remove(info.processName, info.uid);
1884 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001885 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001886 info.processName);
1887 mBadProcesses.remove(info.processName, info.uid);
1888 if (app != null) {
1889 app.bad = false;
1890 }
1891 }
1892 }
1893
1894 if (app == null) {
1895 app = newProcessRecordLocked(null, info, processName);
1896 mProcessNames.put(processName, info.uid, app);
1897 } else {
1898 // If this is a new package in the process, add the package to the list
1899 app.addPackage(info.packageName);
1900 }
1901
1902 // If the system is not ready yet, then hold off on starting this
1903 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001904 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001905 && !isAllowedWhileBooting(info)
1906 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001907 if (!mProcessesOnHold.contains(app)) {
1908 mProcessesOnHold.add(app);
1909 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001910 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001911 return app;
1912 }
1913
1914 startProcessLocked(app, hostingType, hostingNameStr);
1915 return (app.pid != 0) ? app : null;
1916 }
1917
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001918 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1919 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1920 }
1921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001922 private final void startProcessLocked(ProcessRecord app,
1923 String hostingType, String hostingNameStr) {
1924 if (app.pid > 0 && app.pid != MY_PID) {
1925 synchronized (mPidsSelfLocked) {
1926 mPidsSelfLocked.remove(app.pid);
1927 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1928 }
1929 app.pid = 0;
1930 }
1931
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001932 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1933 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001934 mProcessesOnHold.remove(app);
1935
1936 updateCpuStats();
1937
1938 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1939 mProcDeaths[0] = 0;
1940
1941 try {
1942 int uid = app.info.uid;
1943 int[] gids = null;
1944 try {
1945 gids = mContext.getPackageManager().getPackageGids(
1946 app.info.packageName);
1947 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001948 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001949 }
1950 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1951 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1952 && mTopComponent != null
1953 && app.processName.equals(mTopComponent.getPackageName())) {
1954 uid = 0;
1955 }
1956 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1957 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1958 uid = 0;
1959 }
1960 }
1961 int debugFlags = 0;
1962 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1963 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001964 // Also turn on CheckJNI for debuggable apps. It's quite
1965 // awkward to turn on otherwise.
1966 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001967 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001968 // Run the app in safe mode if its manifest requests so or the
1969 // system is booted in safe mode.
1970 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1971 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001972 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001974 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1975 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1976 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001977 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1978 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001980 if ("1".equals(SystemProperties.get("debug.assert"))) {
1981 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1982 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001983
1984 // Start the process. It will either succeed and return a result containing
1985 // the PID of the new process, or else throw a RuntimeException.
1986 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001987 app.processName, uid, uid, gids, debugFlags,
1988 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001989
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001990 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1991 synchronized (bs) {
1992 if (bs.isOnBattery()) {
1993 app.batteryStats.incStartsLocked();
1994 }
1995 }
1996
Jeff Brown3f9dd282011-07-08 20:02:19 -07001997 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001998 app.processName, hostingType,
1999 hostingNameStr != null ? hostingNameStr : "");
2000
2001 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07002002 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002003 }
2004
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002005 StringBuilder buf = mStringBuilder;
2006 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002007 buf.append("Start proc ");
2008 buf.append(app.processName);
2009 buf.append(" for ");
2010 buf.append(hostingType);
2011 if (hostingNameStr != null) {
2012 buf.append(" ");
2013 buf.append(hostingNameStr);
2014 }
2015 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07002016 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002017 buf.append(" uid=");
2018 buf.append(uid);
2019 buf.append(" gids={");
2020 if (gids != null) {
2021 for (int gi=0; gi<gids.length; gi++) {
2022 if (gi != 0) buf.append(", ");
2023 buf.append(gids[gi]);
2024
2025 }
2026 }
2027 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002028 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07002029 app.pid = startResult.pid;
2030 app.usingWrapper = startResult.usingWrapper;
2031 app.removed = false;
2032 synchronized (mPidsSelfLocked) {
2033 this.mPidsSelfLocked.put(startResult.pid, app);
2034 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2035 msg.obj = app;
2036 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2037 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002038 }
2039 } catch (RuntimeException e) {
2040 // XXX do better error recovery.
2041 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002042 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002043 }
2044 }
2045
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002046 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002047 if (resumed) {
2048 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2049 } else {
2050 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2051 }
2052 }
2053
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002054 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002055 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2056 && mTopAction == null) {
2057 // We are running in factory test mode, but unable to find
2058 // the factory test app, so just sit around displaying the
2059 // error message and don't try to start anything.
2060 return false;
2061 }
2062 Intent intent = new Intent(
2063 mTopAction,
2064 mTopData != null ? Uri.parse(mTopData) : null);
2065 intent.setComponent(mTopComponent);
2066 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2067 intent.addCategory(Intent.CATEGORY_HOME);
2068 }
2069 ActivityInfo aInfo =
2070 intent.resolveActivityInfo(mContext.getPackageManager(),
2071 STOCK_PM_FLAGS);
2072 if (aInfo != null) {
2073 intent.setComponent(new ComponentName(
2074 aInfo.applicationInfo.packageName, aInfo.name));
2075 // Don't do this if the home app is currently being
2076 // instrumented.
2077 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2078 aInfo.applicationInfo.uid);
2079 if (app == null || app.instrumentationClass == null) {
2080 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002081 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002082 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002083 }
2084 }
2085
2086
2087 return true;
2088 }
2089
2090 /**
2091 * Starts the "new version setup screen" if appropriate.
2092 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002093 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002094 // Only do this once per boot.
2095 if (mCheckedForSetup) {
2096 return;
2097 }
2098
2099 // We will show this screen if the current one is a different
2100 // version than the last one shown, and we are not running in
2101 // low-level factory test mode.
2102 final ContentResolver resolver = mContext.getContentResolver();
2103 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2104 Settings.Secure.getInt(resolver,
2105 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2106 mCheckedForSetup = true;
2107
2108 // See if we should be showing the platform update setup UI.
2109 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2110 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2111 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2112
2113 // We don't allow third party apps to replace this.
2114 ResolveInfo ri = null;
2115 for (int i=0; ris != null && i<ris.size(); i++) {
2116 if ((ris.get(i).activityInfo.applicationInfo.flags
2117 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2118 ri = ris.get(i);
2119 break;
2120 }
2121 }
2122
2123 if (ri != null) {
2124 String vers = ri.activityInfo.metaData != null
2125 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2126 : null;
2127 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2128 vers = ri.activityInfo.applicationInfo.metaData.getString(
2129 Intent.METADATA_SETUP_VERSION);
2130 }
2131 String lastVers = Settings.Secure.getString(
2132 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2133 if (vers != null && !vers.equals(lastVers)) {
2134 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2135 intent.setComponent(new ComponentName(
2136 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002137 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002138 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002139 }
2140 }
2141 }
2142 }
2143
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002144 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002145 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002146 }
2147
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002148 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002149 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002150 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2151 }
2152 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002153
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002154 public void setFrontActivityScreenCompatMode(int mode) {
2155 synchronized (this) {
2156 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2157 }
2158 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002159
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002160 public int getPackageScreenCompatMode(String packageName) {
2161 synchronized (this) {
2162 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2163 }
2164 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002165
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002166 public void setPackageScreenCompatMode(String packageName, int mode) {
2167 synchronized (this) {
2168 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002169 }
2170 }
2171
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002172 public boolean getPackageAskScreenCompat(String packageName) {
2173 synchronized (this) {
2174 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2175 }
2176 }
2177
2178 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2179 synchronized (this) {
2180 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2181 }
2182 }
2183
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002184 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002185 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002186
2187 final int identHash = System.identityHashCode(r);
2188 updateUsageStats(r, true);
2189
2190 int i = mWatchers.beginBroadcast();
2191 while (i > 0) {
2192 i--;
2193 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2194 if (w != null) {
2195 try {
2196 w.activityResuming(identHash);
2197 } catch (RemoteException e) {
2198 }
2199 }
2200 }
2201 mWatchers.finishBroadcast();
2202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002203
Jeff Sharkeya4620792011-05-20 15:29:23 -07002204 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2205 int i = mProcessObservers.beginBroadcast();
2206 while (i > 0) {
2207 i--;
2208 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2209 if (observer != null) {
2210 try {
2211 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2212 } catch (RemoteException e) {
2213 }
2214 }
2215 }
2216 mProcessObservers.finishBroadcast();
2217 }
2218
2219 private void dispatchProcessDied(int pid, int uid) {
2220 int i = mProcessObservers.beginBroadcast();
2221 while (i > 0) {
2222 i--;
2223 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2224 if (observer != null) {
2225 try {
2226 observer.onProcessDied(pid, uid);
2227 } catch (RemoteException e) {
2228 }
2229 }
2230 }
2231 mProcessObservers.finishBroadcast();
2232 }
2233
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002234 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002235 final int N = mPendingActivityLaunches.size();
2236 if (N <= 0) {
2237 return;
2238 }
2239 for (int i=0; i<N; i++) {
2240 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002241 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002242 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2243 doResume && i == (N-1));
2244 }
2245 mPendingActivityLaunches.clear();
2246 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002247
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002248 public final int startActivity(IApplicationThread caller,
2249 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2250 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002251 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2252 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002253 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002254 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002255 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2256 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002257 }
2258
2259 public final WaitResult startActivityAndWait(IApplicationThread caller,
2260 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2261 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002262 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2263 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002264 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002265 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002266 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002267 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2268 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002269 return res;
2270 }
2271
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002272 public final int startActivityWithConfig(IApplicationThread caller,
2273 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2274 int grantedMode, IBinder resultTo,
2275 String resultWho, int requestCode, boolean onlyIfNeeded,
2276 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002277 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002278 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002279 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002280 }
2281
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002282 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002283 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002284 IBinder resultTo, String resultWho, int requestCode,
2285 int flagsMask, int flagsValues) {
2286 // Refuse possible leaked file descriptors
2287 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2288 throw new IllegalArgumentException("File descriptors passed in Intent");
2289 }
2290
2291 IIntentSender sender = intent.getTarget();
2292 if (!(sender instanceof PendingIntentRecord)) {
2293 throw new IllegalArgumentException("Bad PendingIntent object");
2294 }
2295
2296 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002297
2298 synchronized (this) {
2299 // If this is coming from the currently resumed activity, it is
2300 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002301 if (mMainStack.mResumedActivity != null
2302 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002303 Binder.getCallingUid()) {
2304 mAppSwitchesAllowedTime = 0;
2305 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002306 }
2307
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002308 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002309 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2310 }
2311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 public boolean startNextMatchingActivity(IBinder callingActivity,
2313 Intent intent) {
2314 // Refuse possible leaked file descriptors
2315 if (intent != null && intent.hasFileDescriptors() == true) {
2316 throw new IllegalArgumentException("File descriptors passed in Intent");
2317 }
2318
2319 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002320 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2321 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 return false;
2323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324 if (r.app == null || r.app.thread == null) {
2325 // The caller is not running... d'oh!
2326 return false;
2327 }
2328 intent = new Intent(intent);
2329 // The caller is not allowed to change the data.
2330 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2331 // And we are resetting to find the next component...
2332 intent.setComponent(null);
2333
2334 ActivityInfo aInfo = null;
2335 try {
2336 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002337 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002338 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002339 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002340
2341 // Look for the original activity in the list...
2342 final int N = resolves != null ? resolves.size() : 0;
2343 for (int i=0; i<N; i++) {
2344 ResolveInfo rInfo = resolves.get(i);
2345 if (rInfo.activityInfo.packageName.equals(r.packageName)
2346 && rInfo.activityInfo.name.equals(r.info.name)) {
2347 // We found the current one... the next matching is
2348 // after it.
2349 i++;
2350 if (i<N) {
2351 aInfo = resolves.get(i).activityInfo;
2352 }
2353 break;
2354 }
2355 }
2356 } catch (RemoteException e) {
2357 }
2358
2359 if (aInfo == null) {
2360 // Nobody who is next!
2361 return false;
2362 }
2363
2364 intent.setComponent(new ComponentName(
2365 aInfo.applicationInfo.packageName, aInfo.name));
2366 intent.setFlags(intent.getFlags()&~(
2367 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2368 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2369 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2370 Intent.FLAG_ACTIVITY_NEW_TASK));
2371
2372 // Okay now we need to start the new activity, replacing the
2373 // currently running activity. This is a little tricky because
2374 // we want to start the new one as if the current one is finished,
2375 // but not finish the current one first so that there is no flicker.
2376 // And thus...
2377 final boolean wasFinishing = r.finishing;
2378 r.finishing = true;
2379
2380 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002381 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002382 final String resultWho = r.resultWho;
2383 final int requestCode = r.requestCode;
2384 r.resultTo = null;
2385 if (resultTo != null) {
2386 resultTo.removeResultsLocked(r, resultWho, requestCode);
2387 }
2388
2389 final long origId = Binder.clearCallingIdentity();
2390 // XXX we are not dealing with propagating grantedUriPermissions...
2391 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002392 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002393 r.resolvedType, null, 0, aInfo,
2394 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002395 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 Binder.restoreCallingIdentity(origId);
2397
2398 r.finishing = wasFinishing;
2399 if (res != START_SUCCESS) {
2400 return false;
2401 }
2402 return true;
2403 }
2404 }
2405
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002406 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002407 Intent intent, String resolvedType, IBinder resultTo,
2408 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002409
2410 // This is so super not safe, that only the system (or okay root)
2411 // can do it.
2412 final int callingUid = Binder.getCallingUid();
2413 if (callingUid != 0 && callingUid != Process.myUid()) {
2414 throw new SecurityException(
2415 "startActivityInPackage only available to the system");
2416 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002417
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002418 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002419 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2420 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002421 }
2422
2423 public final int startActivities(IApplicationThread caller,
2424 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2425 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2426 }
2427
2428 public final int startActivitiesInPackage(int uid,
2429 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2430
2431 // This is so super not safe, that only the system (or okay root)
2432 // can do it.
2433 final int callingUid = Binder.getCallingUid();
2434 if (callingUid != 0 && callingUid != Process.myUid()) {
2435 throw new SecurityException(
2436 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002437 }
2438
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002439 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 }
2441
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002442 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002443 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002444 // Quick case: check if the top-most recent task is the same.
2445 if (N > 0 && mRecentTasks.get(0) == task) {
2446 return;
2447 }
2448 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002449 for (int i=0; i<N; i++) {
2450 TaskRecord tr = mRecentTasks.get(i);
2451 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2452 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2453 mRecentTasks.remove(i);
2454 i--;
2455 N--;
2456 if (task.intent == null) {
2457 // If the new recent task we are adding is not fully
2458 // specified, then replace it with the existing recent task.
2459 task = tr;
2460 }
2461 }
2462 }
2463 if (N >= MAX_RECENT_TASKS) {
2464 mRecentTasks.remove(N-1);
2465 }
2466 mRecentTasks.add(0, task);
2467 }
2468
2469 public void setRequestedOrientation(IBinder token,
2470 int requestedOrientation) {
2471 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002472 ActivityRecord r = mMainStack.isInStackLocked(token);
2473 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002474 return;
2475 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002476 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002477 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002478 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002479 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002480 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002481 if (config != null) {
2482 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08002483 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002484 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002485 }
2486 }
2487 Binder.restoreCallingIdentity(origId);
2488 }
2489 }
2490
2491 public int getRequestedOrientation(IBinder token) {
2492 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002493 ActivityRecord r = mMainStack.isInStackLocked(token);
2494 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002495 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2496 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002497 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 }
2499 }
2500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002501 /**
2502 * This is the internal entry point for handling Activity.finish().
2503 *
2504 * @param token The Binder token referencing the Activity we want to finish.
2505 * @param resultCode Result code, if any, from this Activity.
2506 * @param resultData Result data (Intent), if any, from this Activity.
2507 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002508 * @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 -08002509 */
2510 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2511 // Refuse possible leaked file descriptors
2512 if (resultData != null && resultData.hasFileDescriptors() == true) {
2513 throw new IllegalArgumentException("File descriptors passed in Intent");
2514 }
2515
2516 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002517 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002518 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002519 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002520 if (next != null) {
2521 // ask watcher if this is allowed
2522 boolean resumeOK = true;
2523 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002524 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002525 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002526 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002527 }
2528
2529 if (!resumeOK) {
2530 return false;
2531 }
2532 }
2533 }
2534 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002535 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002536 resultData, "app-request");
2537 Binder.restoreCallingIdentity(origId);
2538 return res;
2539 }
2540 }
2541
Dianne Hackborn860755f2010-06-03 18:47:52 -07002542 public final void finishHeavyWeightApp() {
2543 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2544 != PackageManager.PERMISSION_GRANTED) {
2545 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2546 + Binder.getCallingPid()
2547 + ", uid=" + Binder.getCallingUid()
2548 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2549 Slog.w(TAG, msg);
2550 throw new SecurityException(msg);
2551 }
2552
2553 synchronized(this) {
2554 if (mHeavyWeightProcess == null) {
2555 return;
2556 }
2557
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002558 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002559 mHeavyWeightProcess.activities);
2560 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002561 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002562 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002563 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002564 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002565 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002566 null, "finish-heavy");
2567 }
2568 }
2569 }
2570
2571 mHeavyWeightProcess = null;
2572 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2573 }
2574 }
2575
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002576 public void crashApplication(int uid, int initialPid, String packageName,
2577 String message) {
2578 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2579 != PackageManager.PERMISSION_GRANTED) {
2580 String msg = "Permission Denial: crashApplication() from pid="
2581 + Binder.getCallingPid()
2582 + ", uid=" + Binder.getCallingUid()
2583 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2584 Slog.w(TAG, msg);
2585 throw new SecurityException(msg);
2586 }
2587
2588 synchronized(this) {
2589 ProcessRecord proc = null;
2590
2591 // Figure out which process to kill. We don't trust that initialPid
2592 // still has any relation to current pids, so must scan through the
2593 // list.
2594 synchronized (mPidsSelfLocked) {
2595 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2596 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2597 if (p.info.uid != uid) {
2598 continue;
2599 }
2600 if (p.pid == initialPid) {
2601 proc = p;
2602 break;
2603 }
2604 for (String str : p.pkgList) {
2605 if (str.equals(packageName)) {
2606 proc = p;
2607 }
2608 }
2609 }
2610 }
2611
2612 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002613 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002614 + " initialPid=" + initialPid
2615 + " packageName=" + packageName);
2616 return;
2617 }
2618
2619 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002620 if (proc.pid == Process.myPid()) {
2621 Log.w(TAG, "crashApplication: trying to crash self!");
2622 return;
2623 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002624 long ident = Binder.clearCallingIdentity();
2625 try {
2626 proc.thread.scheduleCrash(message);
2627 } catch (RemoteException e) {
2628 }
2629 Binder.restoreCallingIdentity(ident);
2630 }
2631 }
2632 }
2633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002634 public final void finishSubActivity(IBinder token, String resultWho,
2635 int requestCode) {
2636 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002637 ActivityRecord self = mMainStack.isInStackLocked(token);
2638 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 return;
2640 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002641
2642 final long origId = Binder.clearCallingIdentity();
2643
2644 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002645 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2646 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 if (r.resultTo == self && r.requestCode == requestCode) {
2648 if ((r.resultWho == null && resultWho == null) ||
2649 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002650 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002651 Activity.RESULT_CANCELED, null, "request-sub");
2652 }
2653 }
2654 }
2655
2656 Binder.restoreCallingIdentity(origId);
2657 }
2658 }
2659
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002660 public boolean willActivityBeVisible(IBinder token) {
2661 synchronized(this) {
2662 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002663 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2664 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002665 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002666 return true;
2667 }
2668 if (r.fullscreen && !r.finishing) {
2669 return false;
2670 }
2671 }
2672 return true;
2673 }
2674 }
2675
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002676 public void overridePendingTransition(IBinder token, String packageName,
2677 int enterAnim, int exitAnim) {
2678 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002679 ActivityRecord self = mMainStack.isInStackLocked(token);
2680 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002681 return;
2682 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002683
2684 final long origId = Binder.clearCallingIdentity();
2685
2686 if (self.state == ActivityState.RESUMED
2687 || self.state == ActivityState.PAUSING) {
2688 mWindowManager.overridePendingAppTransition(packageName,
2689 enterAnim, exitAnim);
2690 }
2691
2692 Binder.restoreCallingIdentity(origId);
2693 }
2694 }
2695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002696 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697 * Main function for removing an existing process from the activity manager
2698 * as a result of that process going away. Clears out all connections
2699 * to the process.
2700 */
2701 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002702 boolean restarting, boolean allowRestart) {
2703 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002704 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002705 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002706 }
2707
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002708 if (mProfileProc == app) {
2709 clearProfilerLocked();
2710 }
2711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002712 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002713 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2714 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2715 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002717 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2718 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 }
2720
2721 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002722 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002723
2724 boolean atTop = true;
2725 boolean hasVisibleActivities = false;
2726
2727 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002728 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002729 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002730 TAG, "Removing app " + app + " from history with " + i + " entries");
2731 while (i > 0) {
2732 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002733 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002734 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002735 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2736 if (r.app == app) {
2737 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002738 if (ActivityStack.DEBUG_ADD_REMOVE) {
2739 RuntimeException here = new RuntimeException("here");
2740 here.fillInStackTrace();
2741 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2742 + ": haveState=" + r.haveState
2743 + " stateNotNeeded=" + r.stateNotNeeded
2744 + " finishing=" + r.finishing
2745 + " state=" + r.state, here);
2746 }
2747 if (!r.finishing) {
2748 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -08002749 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2750 System.identityHashCode(r),
2751 r.task.taskId, r.shortComponentName,
2752 "proc died without state saved");
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002753 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002754 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002755 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002756 r.takeFromHistory();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002757 mWindowManager.removeAppToken(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002758 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002759 mMainStack.validateAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002760 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002761 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002762
2763 } else {
2764 // We have the current state for this activity, so
2765 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002766 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767 TAG, "Keeping entry, setting app to null");
2768 if (r.visible) {
2769 hasVisibleActivities = true;
2770 }
2771 r.app = null;
2772 r.nowVisible = false;
2773 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002774 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2775 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002776 r.icicle = null;
2777 }
2778 }
2779
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002780 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002781 }
2782 atTop = false;
2783 }
2784
2785 app.activities.clear();
2786
2787 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002788 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002789 + " running instrumentation " + app.instrumentationClass);
2790 Bundle info = new Bundle();
2791 info.putString("shortMsg", "Process crashed.");
2792 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2793 }
2794
2795 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002796 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002797 // If there was nothing to resume, and we are not already
2798 // restarting this process, but there is a visible activity that
2799 // is hosted by the process... then make sure all visible
2800 // activities are running, taking care of restarting this
2801 // process.
2802 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002803 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002804 }
2805 }
2806 }
2807 }
2808
2809 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2810 IBinder threadBinder = thread.asBinder();
2811
2812 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002813 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2814 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002815 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2816 return i;
2817 }
2818 }
2819 return -1;
2820 }
2821
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002822 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002823 IApplicationThread thread) {
2824 if (thread == null) {
2825 return null;
2826 }
2827
2828 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002829 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002830 }
2831
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002832 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002833 IApplicationThread thread) {
2834
2835 mProcDeaths[0]++;
2836
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002837 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2838 synchronized (stats) {
2839 stats.noteProcessDiedLocked(app.info.uid, pid);
2840 }
2841
Magnus Edlund7bb25812010-02-24 15:45:06 +01002842 // Clean up already done if the process has been re-started.
2843 if (app.pid == pid && app.thread != null &&
2844 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002845 if (!app.killedBackground) {
2846 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2847 + ") has died.");
2848 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002849 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002850 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 TAG, "Dying app: " + app + ", pid: " + pid
2852 + ", thread: " + thread.asBinder());
2853 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002854 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002855
2856 if (doLowMem) {
2857 // If there are no longer any background processes running,
2858 // and the app that died was not running instrumentation,
2859 // then tell everyone we are now low on memory.
2860 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002861 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2862 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002863 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002864 haveBg = true;
2865 break;
2866 }
2867 }
2868
2869 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002870 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002871 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002872 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2873 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002874 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002875 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2876 // The low memory report is overriding any current
2877 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002878 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002879 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002880 rec.lastRequestedGc = 0;
2881 } else {
2882 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002883 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002884 rec.reportLowMemory = true;
2885 rec.lastLowMemory = now;
2886 mProcessesToGc.remove(rec);
2887 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002888 }
2889 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002890 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002891 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002892 }
2893 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002894 } else if (app.pid != pid) {
2895 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002896 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002897 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002898 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002899 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002900 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002901 + thread.asBinder());
2902 }
2903 }
2904
Dan Egnor42471dd2010-01-07 17:25:22 -08002905 /**
2906 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002907 * @param clearTraces causes the dump file to be erased prior to the new
2908 * traces being written, if true; when false, the new traces will be
2909 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002910 * @param firstPids of dalvik VM processes to dump stack traces for first
2911 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002912 * @return file containing stack traces, or null if no dump file is configured
2913 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002914 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2915 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002916 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2917 if (tracesPath == null || tracesPath.length() == 0) {
2918 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002919 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002920
2921 File tracesFile = new File(tracesPath);
2922 try {
2923 File tracesDir = tracesFile.getParentFile();
2924 if (!tracesDir.exists()) tracesFile.mkdirs();
2925 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2926
Christopher Tate6ee412d2010-05-28 12:01:56 -07002927 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002928 tracesFile.createNewFile();
2929 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2930 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002931 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002932 return null;
2933 }
2934
2935 // Use a FileObserver to detect when traces finish writing.
2936 // The order of traces is considered important to maintain for legibility.
2937 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2938 public synchronized void onEvent(int event, String path) { notify(); }
2939 };
2940
2941 try {
2942 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002943
2944 // First collect all of the stacks of the most important pids.
2945 try {
2946 int num = firstPids.size();
2947 for (int i = 0; i < num; i++) {
2948 synchronized (observer) {
2949 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2950 observer.wait(200); // Wait for write-close, give up after 200msec
2951 }
2952 }
2953 } catch (InterruptedException e) {
2954 Log.wtf(TAG, e);
2955 }
2956
2957 // Next measure CPU usage.
2958 if (processStats != null) {
2959 processStats.init();
2960 System.gc();
2961 processStats.update();
2962 try {
2963 synchronized (processStats) {
2964 processStats.wait(500); // measure over 1/2 second.
2965 }
2966 } catch (InterruptedException e) {
2967 }
2968 processStats.update();
2969
2970 // We'll take the stack crawls of just the top apps using CPU.
2971 final int N = processStats.countWorkingStats();
2972 int numProcs = 0;
2973 for (int i=0; i<N && numProcs<5; i++) {
2974 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2975 if (lastPids.indexOfKey(stats.pid) >= 0) {
2976 numProcs++;
2977 try {
2978 synchronized (observer) {
2979 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2980 observer.wait(200); // Wait for write-close, give up after 200msec
2981 }
2982 } catch (InterruptedException e) {
2983 Log.wtf(TAG, e);
2984 }
2985
2986 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002987 }
2988 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002989
2990 return tracesFile;
2991
Dan Egnor42471dd2010-01-07 17:25:22 -08002992 } finally {
2993 observer.stopWatching();
2994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 }
2996
Jeff Brown4d94a762010-09-23 11:33:28 -07002997 private final class AppNotResponding implements Runnable {
2998 private final ProcessRecord mApp;
2999 private final String mAnnotation;
3000
3001 public AppNotResponding(ProcessRecord app, String annotation) {
3002 mApp = app;
3003 mAnnotation = annotation;
3004 }
3005
3006 @Override
3007 public void run() {
3008 appNotResponding(mApp, null, null, mAnnotation);
3009 }
3010 }
3011
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003012 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3013 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003014 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3015 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3016
Dianne Hackborn287952c2010-09-22 22:34:31 -07003017 if (mController != null) {
3018 try {
3019 // 0 == continue, -1 = kill process immediately
3020 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3021 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3022 } catch (RemoteException e) {
3023 mController = null;
3024 }
3025 }
3026
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003027 long anrTime = SystemClock.uptimeMillis();
3028 if (MONITOR_CPU_USAGE) {
3029 updateCpuStatsNow();
3030 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003031
3032 synchronized (this) {
3033 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3034 if (mShuttingDown) {
3035 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3036 return;
3037 } else if (app.notResponding) {
3038 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3039 return;
3040 } else if (app.crashing) {
3041 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3042 return;
3043 }
3044
3045 // In case we come through here for the same app before completing
3046 // this one, mark as anring now so we will bail out.
3047 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003048
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003049 // Log the ANR to the event log.
3050 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3051 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003052
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003053 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003054 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003055
3056 int parentPid = app.pid;
3057 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003058 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003059
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003060 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003061
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003062 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3063 ProcessRecord r = mLruProcesses.get(i);
3064 if (r != null && r.thread != null) {
3065 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003066 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3067 if (r.persistent) {
3068 firstPids.add(pid);
3069 } else {
3070 lastPids.put(pid, Boolean.TRUE);
3071 }
3072 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003073 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003074 }
3075 }
3076
Dan Egnor42471dd2010-01-07 17:25:22 -08003077 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003078 StringBuilder info = mStringBuilder;
3079 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003080 info.append("ANR in ").append(app.processName);
3081 if (activity != null && activity.shortComponentName != null) {
3082 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003083 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003084 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003085 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003086 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003088 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003089 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003090 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003091
Dianne Hackborn287952c2010-09-22 22:34:31 -07003092 final ProcessStats processStats = new ProcessStats(true);
3093
3094 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3095
Dan Egnor42471dd2010-01-07 17:25:22 -08003096 String cpuInfo = null;
3097 if (MONITOR_CPU_USAGE) {
3098 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003099 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003100 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003101 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003102 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003103 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003104 }
3105
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003106 info.append(processStats.printCurrentState(anrTime));
3107
Joe Onorato8a9b2202010-02-26 18:56:32 -08003108 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003109 if (tracesFile == null) {
3110 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3111 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3112 }
3113
Jeff Sharkeya353d262011-10-28 11:12:06 -07003114 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3115 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003116
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003117 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003118 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003119 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3120 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003121 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003122 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3123 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003124 }
3125 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003126 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003127 }
3128 }
3129
Dan Egnor42471dd2010-01-07 17:25:22 -08003130 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3131 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3132 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003133
3134 synchronized (this) {
3135 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003136 Slog.w(TAG, "Killing " + app + ": background ANR");
3137 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3138 app.processName, app.setAdj, "background ANR");
3139 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003140 return;
3141 }
3142
3143 // Set the app's notResponding state, and look up the errorReportReceiver
3144 makeAppNotRespondingLocked(app,
3145 activity != null ? activity.shortComponentName : null,
3146 annotation != null ? "ANR " + annotation : "ANR",
3147 info.toString());
3148
3149 // Bring up the infamous App Not Responding dialog
3150 Message msg = Message.obtain();
3151 HashMap map = new HashMap();
3152 msg.what = SHOW_NOT_RESPONDING_MSG;
3153 msg.obj = map;
3154 map.put("app", app);
3155 if (activity != null) {
3156 map.put("activity", activity);
3157 }
3158
3159 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003161 }
3162
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003163 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3164 if (!mLaunchWarningShown) {
3165 mLaunchWarningShown = true;
3166 mHandler.post(new Runnable() {
3167 @Override
3168 public void run() {
3169 synchronized (ActivityManagerService.this) {
3170 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3171 d.show();
3172 mHandler.postDelayed(new Runnable() {
3173 @Override
3174 public void run() {
3175 synchronized (ActivityManagerService.this) {
3176 d.dismiss();
3177 mLaunchWarningShown = false;
3178 }
3179 }
3180 }, 4000);
3181 }
3182 }
3183 });
3184 }
3185 }
3186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003187 public boolean clearApplicationUserData(final String packageName,
3188 final IPackageDataObserver observer) {
3189 int uid = Binder.getCallingUid();
3190 int pid = Binder.getCallingPid();
3191 long callingId = Binder.clearCallingIdentity();
3192 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003193 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003194 int pkgUid = -1;
3195 synchronized(this) {
3196 try {
3197 pkgUid = pm.getPackageUid(packageName);
3198 } catch (RemoteException e) {
3199 }
3200 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003201 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003202 return false;
3203 }
3204 if (uid == pkgUid || checkComponentPermission(
3205 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003206 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003207 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003208 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003209 } else {
3210 throw new SecurityException(pid+" does not have permission:"+
3211 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3212 "for process:"+packageName);
3213 }
3214 }
3215
3216 try {
3217 //clear application user data
3218 pm.clearApplicationUserData(packageName, observer);
3219 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3220 Uri.fromParts("package", packageName, null));
3221 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003222 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3223 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003224 } catch (RemoteException e) {
3225 }
3226 } finally {
3227 Binder.restoreCallingIdentity(callingId);
3228 }
3229 return true;
3230 }
3231
Dianne Hackborn03abb812010-01-04 18:43:19 -08003232 public void killBackgroundProcesses(final String packageName) {
3233 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3234 != PackageManager.PERMISSION_GRANTED &&
3235 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3236 != PackageManager.PERMISSION_GRANTED) {
3237 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003238 + Binder.getCallingPid()
3239 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003240 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003241 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003242 throw new SecurityException(msg);
3243 }
3244
3245 long callingId = Binder.clearCallingIdentity();
3246 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003247 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003248 int pkgUid = -1;
3249 synchronized(this) {
3250 try {
3251 pkgUid = pm.getPackageUid(packageName);
3252 } catch (RemoteException e) {
3253 }
3254 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003255 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003256 return;
3257 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003258 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003259 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3260 }
3261 } finally {
3262 Binder.restoreCallingIdentity(callingId);
3263 }
3264 }
3265
3266 public void killAllBackgroundProcesses() {
3267 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3268 != PackageManager.PERMISSION_GRANTED) {
3269 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3270 + Binder.getCallingPid()
3271 + ", uid=" + Binder.getCallingUid()
3272 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3273 Slog.w(TAG, msg);
3274 throw new SecurityException(msg);
3275 }
3276
3277 long callingId = Binder.clearCallingIdentity();
3278 try {
3279 synchronized(this) {
3280 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3281 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3282 final int NA = apps.size();
3283 for (int ia=0; ia<NA; ia++) {
3284 ProcessRecord app = apps.valueAt(ia);
3285 if (app.persistent) {
3286 // we don't kill persistent processes
3287 continue;
3288 }
3289 if (app.removed) {
3290 procs.add(app);
3291 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3292 app.removed = true;
3293 procs.add(app);
3294 }
3295 }
3296 }
3297
3298 int N = procs.size();
3299 for (int i=0; i<N; i++) {
3300 removeProcessLocked(procs.get(i), false, true, "kill all background");
3301 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003302 }
3303 } finally {
3304 Binder.restoreCallingIdentity(callingId);
3305 }
3306 }
3307
3308 public void forceStopPackage(final String packageName) {
3309 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3310 != PackageManager.PERMISSION_GRANTED) {
3311 String msg = "Permission Denial: forceStopPackage() from pid="
3312 + Binder.getCallingPid()
3313 + ", uid=" + Binder.getCallingUid()
3314 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003315 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003316 throw new SecurityException(msg);
3317 }
3318
3319 long callingId = Binder.clearCallingIdentity();
3320 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003321 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003322 int pkgUid = -1;
3323 synchronized(this) {
3324 try {
3325 pkgUid = pm.getPackageUid(packageName);
3326 } catch (RemoteException e) {
3327 }
3328 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003329 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003330 return;
3331 }
3332 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003333 try {
3334 pm.setPackageStoppedState(packageName, true);
3335 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003336 } catch (IllegalArgumentException e) {
3337 Slog.w(TAG, "Failed trying to unstop package "
3338 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003339 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003340 }
3341 } finally {
3342 Binder.restoreCallingIdentity(callingId);
3343 }
3344 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003345
3346 /*
3347 * The pkg name and uid have to be specified.
3348 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3349 */
3350 public void killApplicationWithUid(String pkg, int uid) {
3351 if (pkg == null) {
3352 return;
3353 }
3354 // Make sure the uid is valid.
3355 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003356 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003357 return;
3358 }
3359 int callerUid = Binder.getCallingUid();
3360 // Only the system server can kill an application
3361 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003362 // Post an aysnc message to kill the application
3363 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3364 msg.arg1 = uid;
3365 msg.arg2 = 0;
3366 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003367 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003368 } else {
3369 throw new SecurityException(callerUid + " cannot kill pkg: " +
3370 pkg);
3371 }
3372 }
3373
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003374 public void closeSystemDialogs(String reason) {
3375 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003376 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003377 if (reason != null) {
3378 intent.putExtra("reason", reason);
3379 }
3380
3381 final int uid = Binder.getCallingUid();
3382 final long origId = Binder.clearCallingIdentity();
3383 synchronized (this) {
3384 int i = mWatchers.beginBroadcast();
3385 while (i > 0) {
3386 i--;
3387 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3388 if (w != null) {
3389 try {
3390 w.closingSystemDialogs(reason);
3391 } catch (RemoteException e) {
3392 }
3393 }
3394 }
3395 mWatchers.finishBroadcast();
3396
Dianne Hackbornffa42482009-09-23 22:20:11 -07003397 mWindowManager.closeSystemDialogs(reason);
3398
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003399 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3400 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003401 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003402 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003403 Activity.RESULT_CANCELED, null, "close-sys");
3404 }
3405 }
3406
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003407 broadcastIntentLocked(null, null, intent, null,
3408 null, 0, null, null, null, false, false, -1, uid);
3409 }
3410 Binder.restoreCallingIdentity(origId);
3411 }
3412
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003413 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003414 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003415 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3416 for (int i=pids.length-1; i>=0; i--) {
3417 infos[i] = new Debug.MemoryInfo();
3418 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003419 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003420 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003421 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003422
Dianne Hackbornb437e092011-08-05 17:50:29 -07003423 public long[] getProcessPss(int[] pids) throws RemoteException {
3424 long[] pss = new long[pids.length];
3425 for (int i=pids.length-1; i>=0; i--) {
3426 pss[i] = Debug.getPss(pids[i]);
3427 }
3428 return pss;
3429 }
3430
Christopher Tate5e1ab332009-09-01 20:32:49 -07003431 public void killApplicationProcess(String processName, int uid) {
3432 if (processName == null) {
3433 return;
3434 }
3435
3436 int callerUid = Binder.getCallingUid();
3437 // Only the system server can kill an application
3438 if (callerUid == Process.SYSTEM_UID) {
3439 synchronized (this) {
3440 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003441 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003442 try {
3443 app.thread.scheduleSuicide();
3444 } catch (RemoteException e) {
3445 // If the other end already died, then our work here is done.
3446 }
3447 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003448 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003449 + processName + " / " + uid);
3450 }
3451 }
3452 } else {
3453 throw new SecurityException(callerUid + " cannot kill app process: " +
3454 processName);
3455 }
3456 }
3457
Dianne Hackborn03abb812010-01-04 18:43:19 -08003458 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003459 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003460 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3461 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003462 if (!mProcessesReady) {
3463 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003465 intent.putExtra(Intent.EXTRA_UID, uid);
3466 broadcastIntentLocked(null, null, intent,
3467 null, null, 0, null, null, null,
3468 false, false, MY_PID, Process.SYSTEM_UID);
3469 }
3470
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003471 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003472 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003473 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003474 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003475
Dianne Hackborn03abb812010-01-04 18:43:19 -08003476 // Remove all processes this package may have touched: all with the
3477 // same UID (except for the system or root user), and all whose name
3478 // matches the package name.
3479 final String procNamePrefix = packageName + ":";
3480 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3481 final int NA = apps.size();
3482 for (int ia=0; ia<NA; ia++) {
3483 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003484 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003485 // we don't kill persistent processes
3486 continue;
3487 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003488 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003489 if (doit) {
3490 procs.add(app);
3491 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003492 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3493 || app.processName.equals(packageName)
3494 || app.processName.startsWith(procNamePrefix)) {
3495 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003496 if (!doit) {
3497 return true;
3498 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003499 app.removed = true;
3500 procs.add(app);
3501 }
3502 }
3503 }
3504 }
3505
3506 int N = procs.size();
3507 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003508 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003509 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003510 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003511 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003512
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003513 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003514 boolean callerWillRestart, boolean purgeCache, boolean doit,
3515 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003516 int i;
3517 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003519 if (uid < 0) {
3520 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003521 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003522 } catch (RemoteException e) {
3523 }
3524 }
3525
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003526 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003527 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003528
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003529 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3530 while (badApps.hasNext()) {
3531 SparseArray<Long> ba = badApps.next();
3532 if (ba.get(uid) != null) {
3533 badApps.remove();
3534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003535 }
3536 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003537
3538 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003539 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003540
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003541 TaskRecord lastTask = null;
3542 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003543 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003544 final boolean samePackage = r.packageName.equals(name);
3545 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003546 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003547 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003548 if (r.finishing) {
3549 // If this activity is just finishing, then it is not
3550 // interesting as far as something to stop.
3551 continue;
3552 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003553 return true;
3554 }
3555 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003556 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003557 if (samePackage) {
3558 if (r.app != null) {
3559 r.app.removed = true;
3560 }
3561 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003562 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003563 lastTask = r.task;
3564 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3565 null, "force-stop")) {
3566 i--;
3567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003568 }
3569 }
3570
3571 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3572 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003573 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003574 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003575 if (!doit) {
3576 return true;
3577 }
3578 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003579 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003580 if (service.app != null) {
3581 service.app.removed = true;
3582 }
3583 service.app = null;
3584 services.add(service);
3585 }
3586 }
3587
3588 N = services.size();
3589 for (i=0; i<N; i++) {
3590 bringDownServiceLocked(services.get(i), true);
3591 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003592
3593 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3594 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3595 if (provider.info.packageName.equals(name)
3596 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3597 if (!doit) {
3598 return true;
3599 }
3600 didSomething = true;
3601 providers.add(provider);
3602 }
3603 }
3604
3605 N = providers.size();
3606 for (i=0; i<N; i++) {
3607 removeDyingProviderLocked(null, providers.get(i));
3608 }
3609
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003610 if (doit) {
3611 if (purgeCache) {
3612 AttributeCache ac = AttributeCache.instance();
3613 if (ac != null) {
3614 ac.removePackage(name);
3615 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003616 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003617 if (mBooted) {
3618 mMainStack.resumeTopActivityLocked(null);
3619 mMainStack.scheduleIdleLocked();
3620 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003621 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003622
3623 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003624 }
3625
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003626 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003627 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003628 final String name = app.processName;
3629 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003630 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003631 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 + "/" + uid + ")");
3633
3634 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003635 if (mHeavyWeightProcess == app) {
3636 mHeavyWeightProcess = null;
3637 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3638 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003639 boolean needRestart = false;
3640 if (app.pid > 0 && app.pid != MY_PID) {
3641 int pid = app.pid;
3642 synchronized (mPidsSelfLocked) {
3643 mPidsSelfLocked.remove(pid);
3644 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3645 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003646 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003647 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003648 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003649 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003650
3651 if (app.persistent) {
3652 if (!callerWillRestart) {
3653 addAppLocked(app.info);
3654 } else {
3655 needRestart = true;
3656 }
3657 }
3658 } else {
3659 mRemovedProcesses.add(app);
3660 }
3661
3662 return needRestart;
3663 }
3664
3665 private final void processStartTimedOutLocked(ProcessRecord app) {
3666 final int pid = app.pid;
3667 boolean gone = false;
3668 synchronized (mPidsSelfLocked) {
3669 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3670 if (knownApp != null && knownApp.thread == null) {
3671 mPidsSelfLocked.remove(pid);
3672 gone = true;
3673 }
3674 }
3675
3676 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003677 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003678 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003679 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003681 if (mHeavyWeightProcess == app) {
3682 mHeavyWeightProcess = null;
3683 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3684 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003685 // Take care of any launching providers waiting for this process.
3686 checkAppInLaunchingProvidersLocked(app, true);
3687 // Take care of any services that are waiting for the process.
3688 for (int i=0; i<mPendingServices.size(); i++) {
3689 ServiceRecord sr = mPendingServices.get(i);
3690 if (app.info.uid == sr.appInfo.uid
3691 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003692 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003693 mPendingServices.remove(i);
3694 i--;
3695 bringDownServiceLocked(sr, true);
3696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003697 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003698 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3699 app.processName, app.setAdj, "start timeout");
3700 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003701 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003702 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003703 try {
3704 IBackupManager bm = IBackupManager.Stub.asInterface(
3705 ServiceManager.getService(Context.BACKUP_SERVICE));
3706 bm.agentDisconnected(app.info.packageName);
3707 } catch (RemoteException e) {
3708 // Can't happen; the backup manager is local
3709 }
3710 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003711 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003712 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003713 mPendingBroadcast.state = BroadcastRecord.IDLE;
3714 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003715 mPendingBroadcast = null;
3716 scheduleBroadcastsLocked();
3717 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003719 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003720 }
3721 }
3722
3723 private final boolean attachApplicationLocked(IApplicationThread thread,
3724 int pid) {
3725
3726 // Find the application record that is being attached... either via
3727 // the pid if we are running in multiple processes, or just pull the
3728 // next app record if we are emulating process with anonymous threads.
3729 ProcessRecord app;
3730 if (pid != MY_PID && pid >= 0) {
3731 synchronized (mPidsSelfLocked) {
3732 app = mPidsSelfLocked.get(pid);
3733 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003734 } else {
3735 app = null;
3736 }
3737
3738 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003739 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003740 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003741 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003742 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003743 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 } else {
3745 try {
3746 thread.scheduleExit();
3747 } catch (Exception e) {
3748 // Ignore exceptions.
3749 }
3750 }
3751 return false;
3752 }
3753
3754 // If this application record is still attached to a previous
3755 // process, clean it up now.
3756 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003757 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003758 }
3759
3760 // Tell the process all about itself.
3761
Joe Onorato8a9b2202010-02-26 18:56:32 -08003762 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003763 TAG, "Binding process pid " + pid + " to record " + app);
3764
3765 String processName = app.processName;
3766 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003767 AppDeathRecipient adr = new AppDeathRecipient(
3768 app, pid, thread);
3769 thread.asBinder().linkToDeath(adr, 0);
3770 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003771 } catch (RemoteException e) {
3772 app.resetPackageList();
3773 startProcessLocked(app, "link fail", processName);
3774 return false;
3775 }
3776
Doug Zongker2bec3d42009-12-04 12:52:44 -08003777 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003778
3779 app.thread = thread;
3780 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003781 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3782 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003783 app.forcingToForeground = null;
3784 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003785 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003786 app.debugging = false;
3787
3788 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3789
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003790 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003791 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003792
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003793 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003794 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003795 }
3796
Joe Onorato8a9b2202010-02-26 18:56:32 -08003797 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798 TAG, "New app record " + app
3799 + " thread=" + thread.asBinder() + " pid=" + pid);
3800 try {
3801 int testMode = IApplicationThread.DEBUG_OFF;
3802 if (mDebugApp != null && mDebugApp.equals(processName)) {
3803 testMode = mWaitForDebugger
3804 ? IApplicationThread.DEBUG_WAIT
3805 : IApplicationThread.DEBUG_ON;
3806 app.debugging = true;
3807 if (mDebugTransient) {
3808 mDebugApp = mOrigDebugApp;
3809 mWaitForDebugger = mOrigWaitForDebugger;
3810 }
3811 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003812 String profileFile = app.instrumentationProfileFile;
3813 ParcelFileDescriptor profileFd = null;
3814 boolean profileAutoStop = false;
3815 if (mProfileApp != null && mProfileApp.equals(processName)) {
3816 mProfileProc = app;
3817 profileFile = mProfileFile;
3818 profileFd = mProfileFd;
3819 profileAutoStop = mAutoStopProfiler;
3820 }
3821
Christopher Tate181fafa2009-05-14 11:12:14 -07003822 // If the app is being launched for restore or full backup, set it up specially
3823 boolean isRestrictedBackupMode = false;
3824 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3825 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003826 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003827 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3828 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003829
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003830 ensurePackageDexOpt(app.instrumentationInfo != null
3831 ? app.instrumentationInfo.packageName
3832 : app.info.packageName);
3833 if (app.instrumentationClass != null) {
3834 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003835 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003836 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003837 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003838 ApplicationInfo appInfo = app.instrumentationInfo != null
3839 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003840 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003841 if (profileFd != null) {
3842 profileFd = profileFd.dup();
3843 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003844 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003845 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003846 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003847 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08003848 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003849 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003850 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003851 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003852 } catch (Exception e) {
3853 // todo: Yikes! What should we do? For now we will try to
3854 // start another process, but that could easily get us in
3855 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003856 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003857
3858 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003859 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003860 startProcessLocked(app, "bind fail", processName);
3861 return false;
3862 }
3863
3864 // Remove this record from the list of starting applications.
3865 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003866 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3867 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003868 mProcessesOnHold.remove(app);
3869
3870 boolean badApp = false;
3871 boolean didSomething = false;
3872
3873 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003874 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003875 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3877 && processName.equals(hr.processName)) {
3878 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003879 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003880 didSomething = true;
3881 }
3882 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003883 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003884 + hr.intent.getComponent().flattenToShortString(), e);
3885 badApp = true;
3886 }
3887 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003888 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889 }
3890 }
3891
3892 // Find any services that should be running in this process...
3893 if (!badApp && mPendingServices.size() > 0) {
3894 ServiceRecord sr = null;
3895 try {
3896 for (int i=0; i<mPendingServices.size(); i++) {
3897 sr = mPendingServices.get(i);
3898 if (app.info.uid != sr.appInfo.uid
3899 || !processName.equals(sr.processName)) {
3900 continue;
3901 }
3902
3903 mPendingServices.remove(i);
3904 i--;
3905 realStartServiceLocked(sr, app);
3906 didSomething = true;
3907 }
3908 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003909 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003910 + sr.shortName, e);
3911 badApp = true;
3912 }
3913 }
3914
3915 // Check if the next broadcast receiver is in this process...
3916 BroadcastRecord br = mPendingBroadcast;
3917 if (!badApp && br != null && br.curApp == app) {
3918 try {
3919 mPendingBroadcast = null;
3920 processCurBroadcastLocked(br, app);
3921 didSomething = true;
3922 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003923 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003924 + br.curComponent.flattenToShortString(), e);
3925 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003926 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003927 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3928 br.resultExtras, br.resultAbort, true);
3929 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003930 // We need to reset the state if we fails to start the receiver.
3931 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003932 }
3933 }
3934
Christopher Tate181fafa2009-05-14 11:12:14 -07003935 // Check whether the next backup agent is in this process...
3936 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003937 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003938 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003939 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003940 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3941 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3942 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003943 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003944 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003945 e.printStackTrace();
3946 }
3947 }
3948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 if (badApp) {
3950 // todo: Also need to kill application to deal with all
3951 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003952 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003953 return false;
3954 }
3955
3956 if (!didSomething) {
3957 updateOomAdjLocked();
3958 }
3959
3960 return true;
3961 }
3962
3963 public final void attachApplication(IApplicationThread thread) {
3964 synchronized (this) {
3965 int callingPid = Binder.getCallingPid();
3966 final long origId = Binder.clearCallingIdentity();
3967 attachApplicationLocked(thread, callingPid);
3968 Binder.restoreCallingIdentity(origId);
3969 }
3970 }
3971
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003972 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003973 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003974 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3975 if (stopProfiling) {
3976 synchronized (this) {
3977 if (mProfileProc == r.app) {
3978 if (mProfileFd != null) {
3979 try {
3980 mProfileFd.close();
3981 } catch (IOException e) {
3982 }
3983 clearProfilerLocked();
3984 }
3985 }
3986 }
3987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003988 Binder.restoreCallingIdentity(origId);
3989 }
3990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003991 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003992 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003993 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003994 mWindowManager.enableScreenAfterBoot();
3995 }
3996
Dianne Hackborn661cd522011-08-22 00:26:20 -07003997 public void showBootMessage(final CharSequence msg, final boolean always) {
3998 mWindowManager.showBootMessage(msg, always);
3999 }
4000
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004001 public void dismissKeyguardOnNextActivity() {
4002 synchronized (this) {
4003 mMainStack.dismissKeyguardOnNextActivityLocked();
4004 }
4005 }
4006
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004007 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004008 IntentFilter pkgFilter = new IntentFilter();
4009 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4010 pkgFilter.addDataScheme("package");
4011 mContext.registerReceiver(new BroadcastReceiver() {
4012 @Override
4013 public void onReceive(Context context, Intent intent) {
4014 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4015 if (pkgs != null) {
4016 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004017 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07004018 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004019 setResultCode(Activity.RESULT_OK);
4020 return;
4021 }
4022 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004023 }
4024 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004025 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004026 }, pkgFilter);
4027
4028 synchronized (this) {
4029 // Ensure that any processes we had put on hold are now started
4030 // up.
4031 final int NP = mProcessesOnHold.size();
4032 if (NP > 0) {
4033 ArrayList<ProcessRecord> procs =
4034 new ArrayList<ProcessRecord>(mProcessesOnHold);
4035 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004036 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4037 + procs.get(ip));
4038 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004039 }
4040 }
4041
4042 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004043 // Start looking for apps that are abusing wake locks.
4044 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004045 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004046 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004047 SystemProperties.set("sys.boot_completed", "1");
Guang Zhu191713a2012-01-12 12:02:22 -08004048 SystemProperties.set("dev.bootcomplete", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004049 broadcastIntentLocked(null, null,
4050 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4051 null, null, 0, null, null,
4052 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4053 false, false, MY_PID, Process.SYSTEM_UID);
4054 }
4055 }
4056 }
4057
4058 final void ensureBootCompleted() {
4059 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004060 boolean enableScreen;
4061 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004062 booting = mBooting;
4063 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004064 enableScreen = !mBooted;
4065 mBooted = true;
4066 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004067
4068 if (booting) {
4069 finishBooting();
4070 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004071
4072 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004073 enableScreenAfterBoot();
4074 }
4075 }
4076
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004077 public final void activityPaused(IBinder token) {
4078 final long origId = Binder.clearCallingIdentity();
4079 mMainStack.activityPaused(token, false);
4080 Binder.restoreCallingIdentity(origId);
4081 }
4082
4083 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4084 CharSequence description) {
4085 if (localLOGV) Slog.v(
4086 TAG, "Activity stopped: token=" + token);
4087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004088 // Refuse possible leaked file descriptors
4089 if (icicle != null && icicle.hasFileDescriptors()) {
4090 throw new IllegalArgumentException("File descriptors passed in Bundle");
4091 }
4092
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004093 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004094
4095 final long origId = Binder.clearCallingIdentity();
4096
4097 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004098 r = mMainStack.isInStackLocked(token);
4099 if (r != null) {
4100 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004101 }
4102 }
4103
4104 if (r != null) {
4105 sendPendingThumbnail(r, null, null, null, false);
4106 }
4107
4108 trimApplications();
4109
4110 Binder.restoreCallingIdentity(origId);
4111 }
4112
4113 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004114 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004115 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 }
4117
4118 public String getCallingPackage(IBinder token) {
4119 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004120 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004121 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 }
4123 }
4124
4125 public ComponentName getCallingActivity(IBinder token) {
4126 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004127 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 return r != null ? r.intent.getComponent() : null;
4129 }
4130 }
4131
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004132 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004133 ActivityRecord r = mMainStack.isInStackLocked(token);
4134 if (r == null) {
4135 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004136 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004137 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004138 }
4139
4140 public ComponentName getActivityClassForToken(IBinder token) {
4141 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004142 ActivityRecord r = mMainStack.isInStackLocked(token);
4143 if (r == null) {
4144 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004145 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004146 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004147 }
4148 }
4149
4150 public String getPackageForToken(IBinder token) {
4151 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004152 ActivityRecord r = mMainStack.isInStackLocked(token);
4153 if (r == null) {
4154 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004155 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004156 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004157 }
4158 }
4159
4160 public IIntentSender getIntentSender(int type,
4161 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004162 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004163 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004164 if (intents != null) {
4165 if (intents.length < 1) {
4166 throw new IllegalArgumentException("Intents array length must be >= 1");
4167 }
4168 for (int i=0; i<intents.length; i++) {
4169 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004170 if (intent != null) {
4171 if (intent.hasFileDescriptors()) {
4172 throw new IllegalArgumentException("File descriptors passed in Intent");
4173 }
4174 if (type == INTENT_SENDER_BROADCAST &&
4175 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4176 throw new IllegalArgumentException(
4177 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4178 }
4179 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004180 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004181 }
4182 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004183 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004184 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004185 }
4186 }
4187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004188 synchronized(this) {
4189 int callingUid = Binder.getCallingUid();
4190 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004191 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004192 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004193 .getPackageUid(packageName);
4194 if (uid != Binder.getCallingUid()) {
4195 String msg = "Permission Denial: getIntentSender() from pid="
4196 + Binder.getCallingPid()
4197 + ", uid=" + Binder.getCallingUid()
4198 + ", (need uid=" + uid + ")"
4199 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004200 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004201 throw new SecurityException(msg);
4202 }
4203 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004204
4205 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004206 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004208 } catch (RemoteException e) {
4209 throw new SecurityException(e);
4210 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004211 }
4212 }
4213
4214 IIntentSender getIntentSenderLocked(int type,
4215 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004216 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004217 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004218 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004219 activity = mMainStack.isInStackLocked(token);
4220 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004221 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004222 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004223 if (activity.finishing) {
4224 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004225 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004226 }
4227
4228 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4229 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4230 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4231 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4232 |PendingIntent.FLAG_UPDATE_CURRENT);
4233
4234 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4235 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004236 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004237 WeakReference<PendingIntentRecord> ref;
4238 ref = mIntentSenderRecords.get(key);
4239 PendingIntentRecord rec = ref != null ? ref.get() : null;
4240 if (rec != null) {
4241 if (!cancelCurrent) {
4242 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004243 if (rec.key.requestIntent != null) {
4244 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4245 }
4246 if (intents != null) {
4247 intents[intents.length-1] = rec.key.requestIntent;
4248 rec.key.allIntents = intents;
4249 rec.key.allResolvedTypes = resolvedTypes;
4250 } else {
4251 rec.key.allIntents = null;
4252 rec.key.allResolvedTypes = null;
4253 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004255 return rec;
4256 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004257 rec.canceled = true;
4258 mIntentSenderRecords.remove(key);
4259 }
4260 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004261 return rec;
4262 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004263 rec = new PendingIntentRecord(this, key, callingUid);
4264 mIntentSenderRecords.put(key, rec.ref);
4265 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4266 if (activity.pendingResults == null) {
4267 activity.pendingResults
4268 = new HashSet<WeakReference<PendingIntentRecord>>();
4269 }
4270 activity.pendingResults.add(rec.ref);
4271 }
4272 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004273 }
4274
4275 public void cancelIntentSender(IIntentSender sender) {
4276 if (!(sender instanceof PendingIntentRecord)) {
4277 return;
4278 }
4279 synchronized(this) {
4280 PendingIntentRecord rec = (PendingIntentRecord)sender;
4281 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004282 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004283 .getPackageUid(rec.key.packageName);
4284 if (uid != Binder.getCallingUid()) {
4285 String msg = "Permission Denial: cancelIntentSender() from pid="
4286 + Binder.getCallingPid()
4287 + ", uid=" + Binder.getCallingUid()
4288 + " is not allowed to cancel packges "
4289 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004290 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004291 throw new SecurityException(msg);
4292 }
4293 } catch (RemoteException e) {
4294 throw new SecurityException(e);
4295 }
4296 cancelIntentSenderLocked(rec, true);
4297 }
4298 }
4299
4300 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4301 rec.canceled = true;
4302 mIntentSenderRecords.remove(rec.key);
4303 if (cleanActivity && rec.key.activity != null) {
4304 rec.key.activity.pendingResults.remove(rec.ref);
4305 }
4306 }
4307
4308 public String getPackageForIntentSender(IIntentSender pendingResult) {
4309 if (!(pendingResult instanceof PendingIntentRecord)) {
4310 return null;
4311 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004312 try {
4313 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4314 return res.key.packageName;
4315 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316 }
4317 return null;
4318 }
4319
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004320 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4321 if (!(pendingResult instanceof PendingIntentRecord)) {
4322 return false;
4323 }
4324 try {
4325 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4326 if (res.key.allIntents == null) {
4327 return false;
4328 }
4329 for (int i=0; i<res.key.allIntents.length; i++) {
4330 Intent intent = res.key.allIntents[i];
4331 if (intent.getPackage() != null && intent.getComponent() != null) {
4332 return false;
4333 }
4334 }
4335 return true;
4336 } catch (ClassCastException e) {
4337 }
4338 return false;
4339 }
4340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004341 public void setProcessLimit(int max) {
4342 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4343 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004344 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004345 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004346 mProcessLimitOverride = max;
4347 }
4348 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004349 }
4350
4351 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004352 synchronized (this) {
4353 return mProcessLimitOverride;
4354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004355 }
4356
4357 void foregroundTokenDied(ForegroundToken token) {
4358 synchronized (ActivityManagerService.this) {
4359 synchronized (mPidsSelfLocked) {
4360 ForegroundToken cur
4361 = mForegroundProcesses.get(token.pid);
4362 if (cur != token) {
4363 return;
4364 }
4365 mForegroundProcesses.remove(token.pid);
4366 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4367 if (pr == null) {
4368 return;
4369 }
4370 pr.forcingToForeground = null;
4371 pr.foregroundServices = false;
4372 }
4373 updateOomAdjLocked();
4374 }
4375 }
4376
4377 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4378 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4379 "setProcessForeground()");
4380 synchronized(this) {
4381 boolean changed = false;
4382
4383 synchronized (mPidsSelfLocked) {
4384 ProcessRecord pr = mPidsSelfLocked.get(pid);
4385 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004386 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004387 return;
4388 }
4389 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4390 if (oldToken != null) {
4391 oldToken.token.unlinkToDeath(oldToken, 0);
4392 mForegroundProcesses.remove(pid);
4393 pr.forcingToForeground = null;
4394 changed = true;
4395 }
4396 if (isForeground && token != null) {
4397 ForegroundToken newToken = new ForegroundToken() {
4398 public void binderDied() {
4399 foregroundTokenDied(this);
4400 }
4401 };
4402 newToken.pid = pid;
4403 newToken.token = token;
4404 try {
4405 token.linkToDeath(newToken, 0);
4406 mForegroundProcesses.put(pid, newToken);
4407 pr.forcingToForeground = token;
4408 changed = true;
4409 } catch (RemoteException e) {
4410 // If the process died while doing this, we will later
4411 // do the cleanup with the process death link.
4412 }
4413 }
4414 }
4415
4416 if (changed) {
4417 updateOomAdjLocked();
4418 }
4419 }
4420 }
4421
4422 // =========================================================
4423 // PERMISSIONS
4424 // =========================================================
4425
4426 static class PermissionController extends IPermissionController.Stub {
4427 ActivityManagerService mActivityManagerService;
4428 PermissionController(ActivityManagerService activityManagerService) {
4429 mActivityManagerService = activityManagerService;
4430 }
4431
4432 public boolean checkPermission(String permission, int pid, int uid) {
4433 return mActivityManagerService.checkPermission(permission, pid,
4434 uid) == PackageManager.PERMISSION_GRANTED;
4435 }
4436 }
4437
4438 /**
4439 * This can be called with or without the global lock held.
4440 */
4441 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004442 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004443 // We might be performing an operation on behalf of an indirect binder
4444 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4445 // client identity accordingly before proceeding.
4446 Identity tlsIdentity = sCallerIdentity.get();
4447 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004448 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004449 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4450 uid = tlsIdentity.uid;
4451 pid = tlsIdentity.pid;
4452 }
4453
4454 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004455 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004456 return PackageManager.PERMISSION_GRANTED;
4457 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004458 // If there is a uid that owns whatever is being accessed, it has
4459 // blanket access to it regardless of the permissions it requires.
4460 if (owningUid >= 0 && uid == owningUid) {
4461 return PackageManager.PERMISSION_GRANTED;
4462 }
4463 // If the target is not exported, then nobody else can get to it.
4464 if (!exported) {
4465 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004466 return PackageManager.PERMISSION_DENIED;
4467 }
4468 if (permission == null) {
4469 return PackageManager.PERMISSION_GRANTED;
4470 }
4471 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004472 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004473 .checkUidPermission(permission, uid);
4474 } catch (RemoteException e) {
4475 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004476 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004477 }
4478 return PackageManager.PERMISSION_DENIED;
4479 }
4480
4481 /**
4482 * As the only public entry point for permissions checking, this method
4483 * can enforce the semantic that requesting a check on a null global
4484 * permission is automatically denied. (Internally a null permission
4485 * string is used when calling {@link #checkComponentPermission} in cases
4486 * when only uid-based security is needed.)
4487 *
4488 * This can be called with or without the global lock held.
4489 */
4490 public int checkPermission(String permission, int pid, int uid) {
4491 if (permission == null) {
4492 return PackageManager.PERMISSION_DENIED;
4493 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004494 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 }
4496
4497 /**
4498 * Binder IPC calls go through the public entry point.
4499 * This can be called with or without the global lock held.
4500 */
4501 int checkCallingPermission(String permission) {
4502 return checkPermission(permission,
4503 Binder.getCallingPid(),
4504 Binder.getCallingUid());
4505 }
4506
4507 /**
4508 * This can be called with or without the global lock held.
4509 */
4510 void enforceCallingPermission(String permission, String func) {
4511 if (checkCallingPermission(permission)
4512 == PackageManager.PERMISSION_GRANTED) {
4513 return;
4514 }
4515
4516 String msg = "Permission Denial: " + func + " from pid="
4517 + Binder.getCallingPid()
4518 + ", uid=" + Binder.getCallingUid()
4519 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004520 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521 throw new SecurityException(msg);
4522 }
4523
4524 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004525 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4526 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4527 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4528 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4529 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004530 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004531 // Is the component private from the target uid?
4532 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4533
4534 // Acceptable if the there is no read permission needed from the
4535 // target or the target is holding the read permission.
4536 if (!readPerm) {
4537 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004538 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004539 == PackageManager.PERMISSION_GRANTED)) {
4540 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004541 }
4542 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004543
4544 // Acceptable if the there is no write permission needed from the
4545 // target or the target is holding the read permission.
4546 if (!writePerm) {
4547 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004548 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004549 == PackageManager.PERMISSION_GRANTED)) {
4550 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004551 }
4552 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004553
4554 // Acceptable if there is a path permission matching the URI that
4555 // the target holds the permission on.
4556 PathPermission[] pps = pi.pathPermissions;
4557 if (pps != null && (!readPerm || !writePerm)) {
4558 final String path = uri.getPath();
4559 int i = pps.length;
4560 while (i > 0 && (!readPerm || !writePerm)) {
4561 i--;
4562 PathPermission pp = pps[i];
4563 if (!readPerm) {
4564 final String pprperm = pp.getReadPermission();
4565 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4566 + pprperm + " for " + pp.getPath()
4567 + ": match=" + pp.match(path)
4568 + " check=" + pm.checkUidPermission(pprperm, uid));
4569 if (pprperm != null && pp.match(path) &&
4570 (pm.checkUidPermission(pprperm, uid)
4571 == PackageManager.PERMISSION_GRANTED)) {
4572 readPerm = true;
4573 }
4574 }
4575 if (!writePerm) {
4576 final String ppwperm = pp.getWritePermission();
4577 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4578 + ppwperm + " for " + pp.getPath()
4579 + ": match=" + pp.match(path)
4580 + " check=" + pm.checkUidPermission(ppwperm, uid));
4581 if (ppwperm != null && pp.match(path) &&
4582 (pm.checkUidPermission(ppwperm, uid)
4583 == PackageManager.PERMISSION_GRANTED)) {
4584 writePerm = true;
4585 }
4586 }
4587 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004589 } catch (RemoteException e) {
4590 return false;
4591 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004592
4593 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004594 }
4595
4596 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4597 int modeFlags) {
4598 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004599 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 return true;
4601 }
4602 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4603 if (perms == null) return false;
4604 UriPermission perm = perms.get(uri);
4605 if (perm == null) return false;
4606 return (modeFlags&perm.modeFlags) == modeFlags;
4607 }
4608
4609 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4610 // Another redirected-binder-call permissions check as in
4611 // {@link checkComponentPermission}.
4612 Identity tlsIdentity = sCallerIdentity.get();
4613 if (tlsIdentity != null) {
4614 uid = tlsIdentity.uid;
4615 pid = tlsIdentity.pid;
4616 }
4617
4618 // Our own process gets to do everything.
4619 if (pid == MY_PID) {
4620 return PackageManager.PERMISSION_GRANTED;
4621 }
4622 synchronized(this) {
4623 return checkUriPermissionLocked(uri, uid, modeFlags)
4624 ? PackageManager.PERMISSION_GRANTED
4625 : PackageManager.PERMISSION_DENIED;
4626 }
4627 }
4628
Dianne Hackborn39792d22010-08-19 18:01:52 -07004629 /**
4630 * Check if the targetPkg can be granted permission to access uri by
4631 * the callingUid using the given modeFlags. Throws a security exception
4632 * if callingUid is not allowed to do this. Returns the uid of the target
4633 * if the URI permission grant should be performed; returns -1 if it is not
4634 * needed (for example targetPkg already has permission to access the URI).
4635 */
4636 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4637 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4639 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4640 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004641 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 }
4643
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004644 if (targetPkg != null) {
4645 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4646 "Checking grant " + targetPkg + " permission to " + uri);
4647 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004648
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004649 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650
4651 // If this is not a content: uri, we can't do anything with it.
4652 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004653 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004654 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004655 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656 }
4657
4658 String name = uri.getAuthority();
4659 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004660 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004661 if (cpr != null) {
4662 pi = cpr.info;
4663 } else {
4664 try {
4665 pi = pm.resolveContentProvider(name,
4666 PackageManager.GET_URI_PERMISSION_PATTERNS);
4667 } catch (RemoteException ex) {
4668 }
4669 }
4670 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004671 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004672 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004673 }
4674
4675 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004676 if (targetPkg != null) {
4677 try {
4678 targetUid = pm.getPackageUid(targetPkg);
4679 if (targetUid < 0) {
4680 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4681 "Can't grant URI permission no uid for: " + targetPkg);
4682 return -1;
4683 }
4684 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004685 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004686 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004687 } else {
4688 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004689 }
4690
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004691 if (targetUid >= 0) {
4692 // First... does the target actually need this permission?
4693 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4694 // No need to grant the target this permission.
4695 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4696 "Target " + targetPkg + " already has full permission to " + uri);
4697 return -1;
4698 }
4699 } else {
4700 // First... there is no target package, so can anyone access it?
4701 boolean allowed = pi.exported;
4702 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4703 if (pi.readPermission != null) {
4704 allowed = false;
4705 }
4706 }
4707 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4708 if (pi.writePermission != null) {
4709 allowed = false;
4710 }
4711 }
4712 if (allowed) {
4713 return -1;
4714 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004715 }
4716
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004717 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004718 if (!pi.grantUriPermissions) {
4719 throw new SecurityException("Provider " + pi.packageName
4720 + "/" + pi.name
4721 + " does not allow granting of Uri permissions (uri "
4722 + uri + ")");
4723 }
4724 if (pi.uriPermissionPatterns != null) {
4725 final int N = pi.uriPermissionPatterns.length;
4726 boolean allowed = false;
4727 for (int i=0; i<N; i++) {
4728 if (pi.uriPermissionPatterns[i] != null
4729 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4730 allowed = true;
4731 break;
4732 }
4733 }
4734 if (!allowed) {
4735 throw new SecurityException("Provider " + pi.packageName
4736 + "/" + pi.name
4737 + " does not allow granting of permission to path of Uri "
4738 + uri);
4739 }
4740 }
4741
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004742 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004743 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004744 if (callingUid != Process.myUid()) {
4745 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4746 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4747 throw new SecurityException("Uid " + callingUid
4748 + " does not have permission to uri " + uri);
4749 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004750 }
4751 }
4752
Dianne Hackborn39792d22010-08-19 18:01:52 -07004753 return targetUid;
4754 }
4755
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004756 public int checkGrantUriPermission(int callingUid, String targetPkg,
4757 Uri uri, int modeFlags) {
4758 synchronized(this) {
4759 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4760 }
4761 }
4762
Dianne Hackborn39792d22010-08-19 18:01:52 -07004763 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4764 Uri uri, int modeFlags, UriPermissionOwner owner) {
4765 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4766 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4767 if (modeFlags == 0) {
4768 return;
4769 }
4770
4771 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004772 // to the uri, and the target doesn't. Let's now give this to
4773 // the target.
4774
Joe Onorato8a9b2202010-02-26 18:56:32 -08004775 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004776 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004778 HashMap<Uri, UriPermission> targetUris
4779 = mGrantedUriPermissions.get(targetUid);
4780 if (targetUris == null) {
4781 targetUris = new HashMap<Uri, UriPermission>();
4782 mGrantedUriPermissions.put(targetUid, targetUris);
4783 }
4784
4785 UriPermission perm = targetUris.get(uri);
4786 if (perm == null) {
4787 perm = new UriPermission(targetUid, uri);
4788 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004789 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004791 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004792 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004793 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004794 } else {
4795 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4796 perm.readOwners.add(owner);
4797 owner.addReadPermission(perm);
4798 }
4799 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4800 perm.writeOwners.add(owner);
4801 owner.addWritePermission(perm);
4802 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004803 }
4804 }
4805
Dianne Hackborn39792d22010-08-19 18:01:52 -07004806 void grantUriPermissionLocked(int callingUid,
4807 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004808 if (targetPkg == null) {
4809 throw new NullPointerException("targetPkg");
4810 }
4811
Dianne Hackborn39792d22010-08-19 18:01:52 -07004812 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4813 if (targetUid < 0) {
4814 return;
4815 }
4816
4817 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4818 }
4819
4820 /**
4821 * Like checkGrantUriPermissionLocked, but takes an Intent.
4822 */
4823 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4824 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004825 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004826 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004827 + " from " + intent + "; flags=0x"
4828 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4829
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004830 if (targetPkg == null) {
4831 throw new NullPointerException("targetPkg");
4832 }
4833
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004834 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004835 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004836 }
4837 Uri data = intent.getData();
4838 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004839 return -1;
4840 }
4841 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4842 intent.getFlags());
4843 }
4844
4845 /**
4846 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4847 */
4848 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4849 String targetPkg, Intent intent, UriPermissionOwner owner) {
4850 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4851 intent.getFlags(), owner);
4852 }
4853
4854 void grantUriPermissionFromIntentLocked(int callingUid,
4855 String targetPkg, Intent intent, UriPermissionOwner owner) {
4856 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4857 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004858 return;
4859 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004860
4861 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004862 }
4863
4864 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4865 Uri uri, int modeFlags) {
4866 synchronized(this) {
4867 final ProcessRecord r = getRecordForAppLocked(caller);
4868 if (r == null) {
4869 throw new SecurityException("Unable to find app for caller "
4870 + caller
4871 + " when granting permission to uri " + uri);
4872 }
4873 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004874 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004875 }
4876 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004877 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004878 }
4879
4880 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4881 null);
4882 }
4883 }
4884
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004885 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004886 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4887 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4888 HashMap<Uri, UriPermission> perms
4889 = mGrantedUriPermissions.get(perm.uid);
4890 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004891 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004892 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004893 perms.remove(perm.uri);
4894 if (perms.size() == 0) {
4895 mGrantedUriPermissions.remove(perm.uid);
4896 }
4897 }
4898 }
4899 }
4900
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004901 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4902 int modeFlags) {
4903 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4904 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4905 if (modeFlags == 0) {
4906 return;
4907 }
4908
Joe Onorato8a9b2202010-02-26 18:56:32 -08004909 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004910 "Revoking all granted permissions to " + uri);
4911
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004912 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004913
4914 final String authority = uri.getAuthority();
4915 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004916 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004917 if (cpr != null) {
4918 pi = cpr.info;
4919 } else {
4920 try {
4921 pi = pm.resolveContentProvider(authority,
4922 PackageManager.GET_URI_PERMISSION_PATTERNS);
4923 } catch (RemoteException ex) {
4924 }
4925 }
4926 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004927 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004928 return;
4929 }
4930
4931 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004932 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 // Right now, if you are not the original owner of the permission,
4934 // you are not allowed to revoke it.
4935 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4936 throw new SecurityException("Uid " + callingUid
4937 + " does not have permission to uri " + uri);
4938 //}
4939 }
4940
4941 // Go through all of the permissions and remove any that match.
4942 final List<String> SEGMENTS = uri.getPathSegments();
4943 if (SEGMENTS != null) {
4944 final int NS = SEGMENTS.size();
4945 int N = mGrantedUriPermissions.size();
4946 for (int i=0; i<N; i++) {
4947 HashMap<Uri, UriPermission> perms
4948 = mGrantedUriPermissions.valueAt(i);
4949 Iterator<UriPermission> it = perms.values().iterator();
4950 toploop:
4951 while (it.hasNext()) {
4952 UriPermission perm = it.next();
4953 Uri targetUri = perm.uri;
4954 if (!authority.equals(targetUri.getAuthority())) {
4955 continue;
4956 }
4957 List<String> targetSegments = targetUri.getPathSegments();
4958 if (targetSegments == null) {
4959 continue;
4960 }
4961 if (targetSegments.size() < NS) {
4962 continue;
4963 }
4964 for (int j=0; j<NS; j++) {
4965 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4966 continue toploop;
4967 }
4968 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004969 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004970 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 perm.clearModes(modeFlags);
4972 if (perm.modeFlags == 0) {
4973 it.remove();
4974 }
4975 }
4976 if (perms.size() == 0) {
4977 mGrantedUriPermissions.remove(
4978 mGrantedUriPermissions.keyAt(i));
4979 N--;
4980 i--;
4981 }
4982 }
4983 }
4984 }
4985
4986 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4987 int modeFlags) {
4988 synchronized(this) {
4989 final ProcessRecord r = getRecordForAppLocked(caller);
4990 if (r == null) {
4991 throw new SecurityException("Unable to find app for caller "
4992 + caller
4993 + " when revoking permission to uri " + uri);
4994 }
4995 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004996 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004997 return;
4998 }
4999
5000 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5001 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5002 if (modeFlags == 0) {
5003 return;
5004 }
5005
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005006 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005007
5008 final String authority = uri.getAuthority();
5009 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07005010 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005011 if (cpr != null) {
5012 pi = cpr.info;
5013 } else {
5014 try {
5015 pi = pm.resolveContentProvider(authority,
5016 PackageManager.GET_URI_PERMISSION_PATTERNS);
5017 } catch (RemoteException ex) {
5018 }
5019 }
5020 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005021 Slog.w(TAG, "No content provider found for permission revoke: "
5022 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005023 return;
5024 }
5025
5026 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
5027 }
5028 }
5029
Dianne Hackborn7e269642010-08-25 19:50:20 -07005030 @Override
5031 public IBinder newUriPermissionOwner(String name) {
5032 synchronized(this) {
5033 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5034 return owner.getExternalTokenLocked();
5035 }
5036 }
5037
5038 @Override
5039 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5040 Uri uri, int modeFlags) {
5041 synchronized(this) {
5042 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5043 if (owner == null) {
5044 throw new IllegalArgumentException("Unknown owner: " + token);
5045 }
5046 if (fromUid != Binder.getCallingUid()) {
5047 if (Binder.getCallingUid() != Process.myUid()) {
5048 // Only system code can grant URI permissions on behalf
5049 // of other users.
5050 throw new SecurityException("nice try");
5051 }
5052 }
5053 if (targetPkg == null) {
5054 throw new IllegalArgumentException("null target");
5055 }
5056 if (uri == null) {
5057 throw new IllegalArgumentException("null uri");
5058 }
5059
5060 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5061 }
5062 }
5063
5064 @Override
5065 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5066 synchronized(this) {
5067 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5068 if (owner == null) {
5069 throw new IllegalArgumentException("Unknown owner: " + token);
5070 }
5071
5072 if (uri == null) {
5073 owner.removeUriPermissionsLocked(mode);
5074 } else {
5075 owner.removeUriPermissionLocked(uri, mode);
5076 }
5077 }
5078 }
5079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005080 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5081 synchronized (this) {
5082 ProcessRecord app =
5083 who != null ? getRecordForAppLocked(who) : null;
5084 if (app == null) return;
5085
5086 Message msg = Message.obtain();
5087 msg.what = WAIT_FOR_DEBUGGER_MSG;
5088 msg.obj = app;
5089 msg.arg1 = waiting ? 1 : 0;
5090 mHandler.sendMessage(msg);
5091 }
5092 }
5093
5094 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005095 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5096 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005097 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005098 outInfo.threshold = homeAppMem;
5099 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5100 outInfo.hiddenAppThreshold = hiddenAppMem;
5101 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005102 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005103 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5104 ProcessList.VISIBLE_APP_ADJ);
5105 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5106 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005107 }
5108
5109 // =========================================================
5110 // TASK MANAGEMENT
5111 // =========================================================
5112
5113 public List getTasks(int maxNum, int flags,
5114 IThumbnailReceiver receiver) {
5115 ArrayList list = new ArrayList();
5116
5117 PendingThumbnailsRecord pending = null;
5118 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005119 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005120
5121 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005122 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005123 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5124 + ", receiver=" + receiver);
5125
5126 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5127 != PackageManager.PERMISSION_GRANTED) {
5128 if (receiver != null) {
5129 // If the caller wants to wait for pending thumbnails,
5130 // it ain't gonna get them.
5131 try {
5132 receiver.finished();
5133 } catch (RemoteException ex) {
5134 }
5135 }
5136 String msg = "Permission Denial: getTasks() from pid="
5137 + Binder.getCallingPid()
5138 + ", uid=" + Binder.getCallingUid()
5139 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005140 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005141 throw new SecurityException(msg);
5142 }
5143
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005144 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005145 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005146 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005147 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005148 TaskRecord curTask = null;
5149 int numActivities = 0;
5150 int numRunning = 0;
5151 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005152 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005153 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005154 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005155
5156 // Initialize state for next task if needed.
5157 if (top == null ||
5158 (top.state == ActivityState.INITIALIZING
5159 && top.task == r.task)) {
5160 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005161 curTask = r.task;
5162 numActivities = numRunning = 0;
5163 }
5164
5165 // Add 'r' into the current task.
5166 numActivities++;
5167 if (r.app != null && r.app.thread != null) {
5168 numRunning++;
5169 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005170
Joe Onorato8a9b2202010-02-26 18:56:32 -08005171 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005172 TAG, r.intent.getComponent().flattenToShortString()
5173 + ": task=" + r.task);
5174
5175 // If the next one is a different task, generate a new
5176 // TaskInfo entry for what we have.
5177 if (next == null || next.task != curTask) {
5178 ActivityManager.RunningTaskInfo ci
5179 = new ActivityManager.RunningTaskInfo();
5180 ci.id = curTask.taskId;
5181 ci.baseActivity = r.intent.getComponent();
5182 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005183 if (top.thumbHolder != null) {
5184 ci.description = top.thumbHolder.lastDescription;
5185 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005186 ci.numActivities = numActivities;
5187 ci.numRunning = numRunning;
5188 //System.out.println(
5189 // "#" + maxNum + ": " + " descr=" + ci.description);
5190 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005191 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005192 TAG, "State=" + top.state + "Idle=" + top.idle
5193 + " app=" + top.app
5194 + " thr=" + (top.app != null ? top.app.thread : null));
5195 if (top.state == ActivityState.RESUMED
5196 || top.state == ActivityState.PAUSING) {
5197 if (top.idle && top.app != null
5198 && top.app.thread != null) {
5199 topRecord = top;
5200 topThumbnail = top.app.thread;
5201 } else {
5202 top.thumbnailNeeded = true;
5203 }
5204 }
5205 if (pending == null) {
5206 pending = new PendingThumbnailsRecord(receiver);
5207 }
5208 pending.pendingRecords.add(top);
5209 }
5210 list.add(ci);
5211 maxNum--;
5212 top = null;
5213 }
5214 }
5215
5216 if (pending != null) {
5217 mPendingThumbnails.add(pending);
5218 }
5219 }
5220
Joe Onorato8a9b2202010-02-26 18:56:32 -08005221 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005222
5223 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005224 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005225 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08005226 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005227 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005228 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005229 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005230 }
5231 }
5232
5233 if (pending == null && receiver != null) {
5234 // In this case all thumbnails were available and the client
5235 // is being asked to be told when the remaining ones come in...
5236 // which is unusually, since the top-most currently running
5237 // activity should never have a canned thumbnail! Oh well.
5238 try {
5239 receiver.finished();
5240 } catch (RemoteException ex) {
5241 }
5242 }
5243
5244 return list;
5245 }
5246
5247 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5248 int flags) {
5249 synchronized (this) {
5250 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5251 "getRecentTasks()");
5252
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005253 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005255 final int N = mRecentTasks.size();
5256 ArrayList<ActivityManager.RecentTaskInfo> res
5257 = new ArrayList<ActivityManager.RecentTaskInfo>(
5258 maxNum < N ? maxNum : N);
5259 for (int i=0; i<N && maxNum > 0; i++) {
5260 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005261 // Return the entry if desired by the caller. We always return
5262 // the first entry, because callers always expect this to be the
5263 // forground app. We may filter others if the caller has
5264 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5265 // we should exclude the entry.
5266 if (i == 0
5267 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005268 || (tr.intent == null)
5269 || ((tr.intent.getFlags()
5270 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5271 ActivityManager.RecentTaskInfo rti
5272 = new ActivityManager.RecentTaskInfo();
5273 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005274 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005275 rti.baseIntent = new Intent(
5276 tr.intent != null ? tr.intent : tr.affinityIntent);
5277 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005278 rti.description = tr.lastDescription;
5279
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005280 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5281 // Check whether this activity is currently available.
5282 try {
5283 if (rti.origActivity != null) {
5284 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5285 continue;
5286 }
5287 } else if (rti.baseIntent != null) {
5288 if (pm.queryIntentActivities(rti.baseIntent,
5289 null, 0) == null) {
5290 continue;
5291 }
5292 }
5293 } catch (RemoteException e) {
5294 // Will never happen.
5295 }
5296 }
5297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005298 res.add(rti);
5299 maxNum--;
5300 }
5301 }
5302 return res;
5303 }
5304 }
5305
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005306 private TaskRecord taskForIdLocked(int id) {
5307 final int N = mRecentTasks.size();
5308 for (int i=0; i<N; i++) {
5309 TaskRecord tr = mRecentTasks.get(i);
5310 if (tr.taskId == id) {
5311 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005312 }
5313 }
5314 return null;
5315 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005316
5317 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5318 synchronized (this) {
5319 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5320 "getTaskThumbnails()");
5321 TaskRecord tr = taskForIdLocked(id);
5322 if (tr != null) {
5323 return mMainStack.getTaskThumbnailsLocked(tr);
5324 }
5325 }
5326 return null;
5327 }
5328
5329 public boolean removeSubTask(int taskId, int subTaskIndex) {
5330 synchronized (this) {
5331 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5332 "removeSubTask()");
5333 long ident = Binder.clearCallingIdentity();
5334 try {
5335 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5336 } finally {
5337 Binder.restoreCallingIdentity(ident);
5338 }
5339 }
5340 }
5341
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005342 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005343 TaskRecord tr = root.task;
5344 Intent baseIntent = new Intent(
5345 tr.intent != null ? tr.intent : tr.affinityIntent);
5346 ComponentName component = baseIntent.getComponent();
5347 if (component == null) {
5348 Slog.w(TAG, "Now component for base intent of task: " + tr);
5349 return;
5350 }
5351
5352 // Find any running services associated with this app.
5353 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5354 for (ServiceRecord sr : mServices.values()) {
5355 if (sr.packageName.equals(component.getPackageName())) {
5356 services.add(sr);
5357 }
5358 }
5359
5360 // Take care of any running services associated with the app.
5361 for (int i=0; i<services.size(); i++) {
5362 ServiceRecord sr = services.get(i);
5363 if (sr.startRequested) {
5364 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005365 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005366 stopServiceLocked(sr);
5367 } else {
5368 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5369 sr.makeNextStartId(), baseIntent, -1));
5370 if (sr.app != null && sr.app.thread != null) {
5371 sendServiceArgsLocked(sr, false);
5372 }
5373 }
5374 }
5375 }
5376
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005377 if (killProcesses) {
5378 // Find any running processes associated with this app.
5379 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5380 SparseArray<ProcessRecord> appProcs
5381 = mProcessNames.getMap().get(component.getPackageName());
5382 if (appProcs != null) {
5383 for (int i=0; i<appProcs.size(); i++) {
5384 procs.add(appProcs.valueAt(i));
5385 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005386 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005387
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005388 // Kill the running processes.
5389 for (int i=0; i<procs.size(); i++) {
5390 ProcessRecord pr = procs.get(i);
5391 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5392 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5393 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5394 pr.processName, pr.setAdj, "remove task");
5395 Process.killProcessQuiet(pr.pid);
5396 } else {
5397 pr.waitingToKill = "remove task";
5398 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005399 }
5400 }
5401 }
5402
5403 public boolean removeTask(int taskId, int flags) {
5404 synchronized (this) {
5405 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5406 "removeTask()");
5407 long ident = Binder.clearCallingIdentity();
5408 try {
5409 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5410 if (r != null) {
5411 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005412 cleanUpRemovedTaskLocked(r,
5413 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005414 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005415 } else {
5416 TaskRecord tr = null;
5417 int i=0;
5418 while (i < mRecentTasks.size()) {
5419 TaskRecord t = mRecentTasks.get(i);
5420 if (t.taskId == taskId) {
5421 tr = t;
5422 break;
5423 }
5424 i++;
5425 }
5426 if (tr != null) {
5427 if (tr.numActivities <= 0) {
5428 // Caller is just removing a recent task that is
5429 // not actively running. That is easy!
5430 mRecentTasks.remove(i);
5431 } else {
5432 Slog.w(TAG, "removeTask: task " + taskId
5433 + " does not have activities to remove, "
5434 + " but numActivities=" + tr.numActivities
5435 + ": " + tr);
5436 }
5437 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005438 }
5439 } finally {
5440 Binder.restoreCallingIdentity(ident);
5441 }
5442 }
5443 return false;
5444 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5447 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005448 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005449 TaskRecord jt = startTask;
5450
5451 // First look backwards
5452 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005453 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005454 if (r.task != jt) {
5455 jt = r.task;
5456 if (affinity.equals(jt.affinity)) {
5457 return j;
5458 }
5459 }
5460 }
5461
5462 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005463 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005464 jt = startTask;
5465 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005466 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005467 if (r.task != jt) {
5468 if (affinity.equals(jt.affinity)) {
5469 return j;
5470 }
5471 jt = r.task;
5472 }
5473 }
5474
5475 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005476 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005477 return N-1;
5478 }
5479
5480 return -1;
5481 }
5482
5483 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005484 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005485 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005486 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005487 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5488 "moveTaskToFront()");
5489
5490 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005491 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5492 Binder.getCallingUid(), "Task to front")) {
5493 return;
5494 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005495 final long origId = Binder.clearCallingIdentity();
5496 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005497 TaskRecord tr = taskForIdLocked(task);
5498 if (tr != null) {
5499 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5500 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005501 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005502 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5503 // Caller wants the home activity moved with it. To accomplish this,
5504 // we'll just move the home task to the top first.
5505 mMainStack.moveHomeToFrontLocked();
5506 }
5507 mMainStack.moveTaskToFrontLocked(tr, null);
5508 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005509 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005510 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5511 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005512 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005513 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5514 mMainStack.mUserLeaving = true;
5515 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005516 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5517 // Caller wants the home activity moved with it. To accomplish this,
5518 // we'll just move the home task to the top first.
5519 mMainStack.moveHomeToFrontLocked();
5520 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005521 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005522 return;
5523 }
5524 }
5525 } finally {
5526 Binder.restoreCallingIdentity(origId);
5527 }
5528 }
5529 }
5530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005531 public void moveTaskToBack(int task) {
5532 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5533 "moveTaskToBack()");
5534
5535 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005536 if (mMainStack.mResumedActivity != null
5537 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005538 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5539 Binder.getCallingUid(), "Task to back")) {
5540 return;
5541 }
5542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005543 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005544 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005545 Binder.restoreCallingIdentity(origId);
5546 }
5547 }
5548
5549 /**
5550 * Moves an activity, and all of the other activities within the same task, to the bottom
5551 * of the history stack. The activity's order within the task is unchanged.
5552 *
5553 * @param token A reference to the activity we wish to move
5554 * @param nonRoot If false then this only works if the activity is the root
5555 * of a task; if true it will work for any activity in a task.
5556 * @return Returns true if the move completed, false if not.
5557 */
5558 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5559 synchronized(this) {
5560 final long origId = Binder.clearCallingIdentity();
5561 int taskId = getTaskForActivityLocked(token, !nonRoot);
5562 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005563 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005564 }
5565 Binder.restoreCallingIdentity(origId);
5566 }
5567 return false;
5568 }
5569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005570 public void moveTaskBackwards(int task) {
5571 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5572 "moveTaskBackwards()");
5573
5574 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005575 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5576 Binder.getCallingUid(), "Task backwards")) {
5577 return;
5578 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005579 final long origId = Binder.clearCallingIdentity();
5580 moveTaskBackwardsLocked(task);
5581 Binder.restoreCallingIdentity(origId);
5582 }
5583 }
5584
5585 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005586 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005587 }
5588
5589 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5590 synchronized(this) {
5591 return getTaskForActivityLocked(token, onlyRoot);
5592 }
5593 }
5594
5595 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005596 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005597 TaskRecord lastTask = null;
5598 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005599 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005600 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005601 if (!onlyRoot || lastTask != r.task) {
5602 return r.task.taskId;
5603 }
5604 return -1;
5605 }
5606 lastTask = r.task;
5607 }
5608
5609 return -1;
5610 }
5611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005612 public void finishOtherInstances(IBinder token, ComponentName className) {
5613 synchronized(this) {
5614 final long origId = Binder.clearCallingIdentity();
5615
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005616 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005617 TaskRecord lastTask = null;
5618 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005619 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005620 if (r.realActivity.equals(className)
Dianne Hackbornbe707852011-11-11 14:32:10 -08005621 && r.appToken != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005622 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005623 null, "others")) {
5624 i--;
5625 N--;
5626 }
5627 }
5628 lastTask = r.task;
5629 }
5630
5631 Binder.restoreCallingIdentity(origId);
5632 }
5633 }
5634
5635 // =========================================================
5636 // THUMBNAILS
5637 // =========================================================
5638
5639 public void reportThumbnail(IBinder token,
5640 Bitmap thumbnail, CharSequence description) {
5641 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5642 final long origId = Binder.clearCallingIdentity();
5643 sendPendingThumbnail(null, token, thumbnail, description, true);
5644 Binder.restoreCallingIdentity(origId);
5645 }
5646
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005647 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005648 Bitmap thumbnail, CharSequence description, boolean always) {
5649 TaskRecord task = null;
5650 ArrayList receivers = null;
5651
5652 //System.out.println("Send pending thumbnail: " + r);
5653
5654 synchronized(this) {
5655 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005656 r = mMainStack.isInStackLocked(token);
5657 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005658 return;
5659 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005660 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005661 if (thumbnail == null && r.thumbHolder != null) {
5662 thumbnail = r.thumbHolder.lastThumbnail;
5663 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005664 }
5665 if (thumbnail == null && !always) {
5666 // If there is no thumbnail, and this entry is not actually
5667 // going away, then abort for now and pick up the next
5668 // thumbnail we get.
5669 return;
5670 }
5671 task = r.task;
5672
5673 int N = mPendingThumbnails.size();
5674 int i=0;
5675 while (i<N) {
5676 PendingThumbnailsRecord pr =
5677 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5678 //System.out.println("Looking in " + pr.pendingRecords);
5679 if (pr.pendingRecords.remove(r)) {
5680 if (receivers == null) {
5681 receivers = new ArrayList();
5682 }
5683 receivers.add(pr);
5684 if (pr.pendingRecords.size() == 0) {
5685 pr.finished = true;
5686 mPendingThumbnails.remove(i);
5687 N--;
5688 continue;
5689 }
5690 }
5691 i++;
5692 }
5693 }
5694
5695 if (receivers != null) {
5696 final int N = receivers.size();
5697 for (int i=0; i<N; i++) {
5698 try {
5699 PendingThumbnailsRecord pr =
5700 (PendingThumbnailsRecord)receivers.get(i);
5701 pr.receiver.newThumbnail(
5702 task != null ? task.taskId : -1, thumbnail, description);
5703 if (pr.finished) {
5704 pr.receiver.finished();
5705 }
5706 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005707 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005708 }
5709 }
5710 }
5711 }
5712
5713 // =========================================================
5714 // CONTENT PROVIDERS
5715 // =========================================================
5716
Jeff Brown10e89712011-07-08 18:52:57 -07005717 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5718 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005719 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005720 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005721 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005722 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005723 } catch (RemoteException ex) {
5724 }
5725 if (providers != null) {
5726 final int N = providers.size();
5727 for (int i=0; i<N; i++) {
5728 ProviderInfo cpi =
5729 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005730 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5731 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005732 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005733 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005734 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005735 }
5736 app.pubProviders.put(cpi.name, cpr);
5737 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005738 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005739 }
5740 }
5741 return providers;
5742 }
5743
5744 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005745 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005746 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5747 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5748 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005749 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005750 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005751 return null;
5752 }
5753 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005754 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005755 == PackageManager.PERMISSION_GRANTED) {
5756 return null;
5757 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005758
5759 PathPermission[] pps = cpi.pathPermissions;
5760 if (pps != null) {
5761 int i = pps.length;
5762 while (i > 0) {
5763 i--;
5764 PathPermission pp = pps[i];
5765 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005766 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005767 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005768 return null;
5769 }
5770 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005771 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005772 == PackageManager.PERMISSION_GRANTED) {
5773 return null;
5774 }
5775 }
5776 }
5777
Dianne Hackbornb424b632010-08-18 15:59:05 -07005778 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5779 if (perms != null) {
5780 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5781 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5782 return null;
5783 }
5784 }
5785 }
5786
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005787 String msg;
5788 if (!cpi.exported) {
5789 msg = "Permission Denial: opening provider " + cpi.name
5790 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5791 + ", uid=" + callingUid + ") that is not exported from uid "
5792 + cpi.applicationInfo.uid;
5793 } else {
5794 msg = "Permission Denial: opening provider " + cpi.name
5795 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5796 + ", uid=" + callingUid + ") requires "
5797 + cpi.readPermission + " or " + cpi.writePermission;
5798 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005799 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005800 return msg;
5801 }
5802
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005803 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5804 if (r != null) {
5805 Integer cnt = r.conProviders.get(cpr);
5806 if (DEBUG_PROVIDER) Slog.v(TAG,
5807 "Adding provider requested by "
5808 + r.processName + " from process "
5809 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5810 + " cnt=" + (cnt == null ? 1 : cnt));
5811 if (cnt == null) {
5812 cpr.clients.add(r);
5813 r.conProviders.put(cpr, new Integer(1));
5814 return true;
5815 } else {
5816 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5817 }
5818 } else {
5819 cpr.externals++;
5820 }
5821 return false;
5822 }
5823
5824 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5825 if (r != null) {
5826 Integer cnt = r.conProviders.get(cpr);
5827 if (DEBUG_PROVIDER) Slog.v(TAG,
5828 "Removing provider requested by "
5829 + r.processName + " from process "
5830 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5831 + " cnt=" + cnt);
5832 if (cnt == null || cnt.intValue() <= 1) {
5833 cpr.clients.remove(r);
5834 r.conProviders.remove(cpr);
5835 return true;
5836 } else {
5837 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5838 }
5839 } else {
5840 cpr.externals++;
5841 }
5842 return false;
5843 }
5844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005845 private final ContentProviderHolder getContentProviderImpl(
5846 IApplicationThread caller, String name) {
5847 ContentProviderRecord cpr;
5848 ProviderInfo cpi = null;
5849
5850 synchronized(this) {
5851 ProcessRecord r = null;
5852 if (caller != null) {
5853 r = getRecordForAppLocked(caller);
5854 if (r == null) {
5855 throw new SecurityException(
5856 "Unable to find app for caller " + caller
5857 + " (pid=" + Binder.getCallingPid()
5858 + ") when getting content provider " + name);
5859 }
5860 }
5861
5862 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005863 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005864 boolean providerRunning = cpr != null;
5865 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005866 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005867 String msg;
5868 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5869 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005870 }
5871
5872 if (r != null && cpr.canRunHere(r)) {
5873 // This provider has been published or is in the process
5874 // of being published... but it is also allowed to run
5875 // in the caller's process, so don't make a connection
5876 // and just let the caller instantiate its own instance.
5877 if (cpr.provider != null) {
5878 // don't give caller the provider object, it needs
5879 // to make its own.
5880 cpr = new ContentProviderRecord(cpr);
5881 }
5882 return cpr;
5883 }
5884
5885 final long origId = Binder.clearCallingIdentity();
5886
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005887 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005888 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005889 final boolean countChanged = incProviderCount(r, cpr);
5890 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005891 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005892 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005893 // make sure to count it as being accessed and thus
5894 // back up on the LRU list. This is good because
5895 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005896 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005897 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005898 }
5899
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005900 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005901 if (false) {
5902 if (cpr.name.flattenToShortString().equals(
5903 "com.android.providers.calendar/.CalendarProvider2")) {
5904 Slog.v(TAG, "****************** KILLING "
5905 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005906 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005907 }
5908 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005909 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005910 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5911 // NOTE: there is still a race here where a signal could be
5912 // pending on the process even though we managed to update its
5913 // adj level. Not sure what to do about this, but at least
5914 // the race is now smaller.
5915 if (!success) {
5916 // Uh oh... it looks like the provider's process
5917 // has been killed on us. We need to wait for a new
5918 // process to be started, and make sure its death
5919 // doesn't kill our process.
5920 Slog.i(TAG,
5921 "Existing provider " + cpr.name.flattenToShortString()
5922 + " is crashing; detaching " + r);
5923 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005924 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005925 if (!lastRef) {
5926 // This wasn't the last ref our process had on
5927 // the provider... we have now been killed, bail.
5928 return null;
5929 }
5930 providerRunning = false;
5931 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005932 }
5933
5934 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005935 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005936
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005937 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005938 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005939 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005940 resolveContentProvider(name,
5941 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005942 } catch (RemoteException ex) {
5943 }
5944 if (cpi == null) {
5945 return null;
5946 }
5947
Dianne Hackbornb424b632010-08-18 15:59:05 -07005948 String msg;
5949 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5950 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005951 }
5952
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005953 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005954 && !cpi.processName.equals("system")) {
5955 // If this content provider does not run in the system
5956 // process, and the system is not yet ready to run other
5957 // processes, then fail fast instead of hanging.
5958 throw new IllegalArgumentException(
5959 "Attempt to launch content provider before system ready");
5960 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005961
5962 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5963 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005964 final boolean firstClass = cpr == null;
5965 if (firstClass) {
5966 try {
5967 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005968 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005969 getApplicationInfo(
5970 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005971 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005972 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005973 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005974 + cpi.name);
5975 return null;
5976 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005977 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005978 } catch (RemoteException ex) {
5979 // pm is in same process, this will never happen.
5980 }
5981 }
5982
5983 if (r != null && cpr.canRunHere(r)) {
5984 // If this is a multiprocess provider, then just return its
5985 // info and allow the caller to instantiate it. Only do
5986 // this if the provider is the same user as the caller's
5987 // process, or can run as root (so can be in any process).
5988 return cpr;
5989 }
5990
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005991 if (DEBUG_PROVIDER) {
5992 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005993 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005994 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005995 }
5996
5997 // This is single process, and our app is now connecting to it.
5998 // See if we are already in the process of launching this
5999 // provider.
6000 final int N = mLaunchingProviders.size();
6001 int i;
6002 for (i=0; i<N; i++) {
6003 if (mLaunchingProviders.get(i) == cpr) {
6004 break;
6005 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006006 }
6007
6008 // If the provider is not already being launched, then get it
6009 // started.
6010 if (i >= N) {
6011 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08006012
6013 try {
6014 // Content provider is now in use, its package can't be stopped.
6015 try {
6016 AppGlobals.getPackageManager().setPackageStoppedState(
6017 cpr.appInfo.packageName, false);
6018 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006019 } catch (IllegalArgumentException e) {
6020 Slog.w(TAG, "Failed trying to unstop package "
6021 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006022 }
6023
6024 ProcessRecord proc = startProcessLocked(cpi.processName,
6025 cpr.appInfo, false, 0, "content provider",
6026 new ComponentName(cpi.applicationInfo.packageName,
6027 cpi.name), false);
6028 if (proc == null) {
6029 Slog.w(TAG, "Unable to launch app "
6030 + cpi.applicationInfo.packageName + "/"
6031 + cpi.applicationInfo.uid + " for provider "
6032 + name + ": process is bad");
6033 return null;
6034 }
6035 cpr.launchingApp = proc;
6036 mLaunchingProviders.add(cpr);
6037 } finally {
6038 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006039 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006040 }
6041
6042 // Make sure the provider is published (the same provider class
6043 // may be published under multiple names).
6044 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006045 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006046 }
6047 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006048 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006049 }
6050 }
6051
6052 // Wait for the provider to be published...
6053 synchronized (cpr) {
6054 while (cpr.provider == null) {
6055 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006056 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006057 + cpi.applicationInfo.packageName + "/"
6058 + cpi.applicationInfo.uid + " for provider "
6059 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006060 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006061 cpi.applicationInfo.packageName,
6062 cpi.applicationInfo.uid, name);
6063 return null;
6064 }
6065 try {
6066 cpr.wait();
6067 } catch (InterruptedException ex) {
6068 }
6069 }
6070 }
6071 return cpr;
6072 }
6073
6074 public final ContentProviderHolder getContentProvider(
6075 IApplicationThread caller, String name) {
6076 if (caller == null) {
6077 String msg = "null IApplicationThread when getting content provider "
6078 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006079 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006080 throw new SecurityException(msg);
6081 }
6082
6083 return getContentProviderImpl(caller, name);
6084 }
6085
6086 private ContentProviderHolder getContentProviderExternal(String name) {
6087 return getContentProviderImpl(null, name);
6088 }
6089
6090 /**
6091 * Drop a content provider from a ProcessRecord's bookkeeping
6092 * @param cpr
6093 */
6094 public void removeContentProvider(IApplicationThread caller, String name) {
6095 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006096 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006097 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006098 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006099 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006100 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006101 return;
6102 }
6103 final ProcessRecord r = getRecordForAppLocked(caller);
6104 if (r == null) {
6105 throw new SecurityException(
6106 "Unable to find app for caller " + caller +
6107 " when removing content provider " + name);
6108 }
6109 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006110 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6111 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006112 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08006114 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006115 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006116 return;
6117 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006118 if (decProviderCount(r, localCpr)) {
6119 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07006120 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006121 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006122 }
6123 }
6124
6125 private void removeContentProviderExternal(String name) {
6126 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006127 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006128 if(cpr == null) {
6129 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006130 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006131 return;
6132 }
6133
6134 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006135 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6136 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006137 localCpr.externals--;
6138 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006139 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006140 }
6141 updateOomAdjLocked();
6142 }
6143 }
6144
6145 public final void publishContentProviders(IApplicationThread caller,
6146 List<ContentProviderHolder> providers) {
6147 if (providers == null) {
6148 return;
6149 }
6150
6151 synchronized(this) {
6152 final ProcessRecord r = getRecordForAppLocked(caller);
6153 if (r == null) {
6154 throw new SecurityException(
6155 "Unable to find app for caller " + caller
6156 + " (pid=" + Binder.getCallingPid()
6157 + ") when publishing content providers");
6158 }
6159
6160 final long origId = Binder.clearCallingIdentity();
6161
6162 final int N = providers.size();
6163 for (int i=0; i<N; i++) {
6164 ContentProviderHolder src = providers.get(i);
6165 if (src == null || src.info == null || src.provider == null) {
6166 continue;
6167 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006168 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006169 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006170 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6171 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006172 String names[] = dst.info.authority.split(";");
6173 for (int j = 0; j < names.length; j++) {
6174 mProvidersByName.put(names[j], dst);
6175 }
6176
6177 int NL = mLaunchingProviders.size();
6178 int j;
6179 for (j=0; j<NL; j++) {
6180 if (mLaunchingProviders.get(j) == dst) {
6181 mLaunchingProviders.remove(j);
6182 j--;
6183 NL--;
6184 }
6185 }
6186 synchronized (dst) {
6187 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006188 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006189 dst.notifyAll();
6190 }
6191 updateOomAdjLocked(r);
6192 }
6193 }
6194
6195 Binder.restoreCallingIdentity(origId);
6196 }
6197 }
6198
6199 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006200 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006201 synchronized (mSelf) {
6202 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6203 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006204 if (providers != null) {
6205 for (int i=providers.size()-1; i>=0; i--) {
6206 ProviderInfo pi = (ProviderInfo)providers.get(i);
6207 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6208 Slog.w(TAG, "Not installing system proc provider " + pi.name
6209 + ": not system .apk");
6210 providers.remove(i);
6211 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006212 }
6213 }
6214 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006215 if (providers != null) {
6216 mSystemThread.installSystemProviders(providers);
6217 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006218
6219 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006220
6221 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006222 }
6223
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006224 /**
6225 * Allows app to retrieve the MIME type of a URI without having permission
6226 * to access its content provider.
6227 *
6228 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6229 *
6230 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6231 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6232 */
6233 public String getProviderMimeType(Uri uri) {
6234 final String name = uri.getAuthority();
6235 final long ident = Binder.clearCallingIdentity();
6236 ContentProviderHolder holder = null;
6237
6238 try {
6239 holder = getContentProviderExternal(name);
6240 if (holder != null) {
6241 return holder.provider.getType(uri);
6242 }
6243 } catch (RemoteException e) {
6244 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6245 return null;
6246 } finally {
6247 if (holder != null) {
6248 removeContentProviderExternal(name);
6249 }
6250 Binder.restoreCallingIdentity(ident);
6251 }
6252
6253 return null;
6254 }
6255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006256 // =========================================================
6257 // GLOBAL MANAGEMENT
6258 // =========================================================
6259
6260 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6261 ApplicationInfo info, String customProcess) {
6262 String proc = customProcess != null ? customProcess : info.processName;
6263 BatteryStatsImpl.Uid.Proc ps = null;
6264 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6265 synchronized (stats) {
6266 ps = stats.getProcessStatsLocked(info.uid, proc);
6267 }
6268 return new ProcessRecord(ps, thread, info, proc);
6269 }
6270
6271 final ProcessRecord addAppLocked(ApplicationInfo info) {
6272 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6273
6274 if (app == null) {
6275 app = newProcessRecordLocked(null, info, null);
6276 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006277 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006278 }
6279
Dianne Hackborne7f97212011-02-24 14:40:20 -08006280 // This package really, really can not be stopped.
6281 try {
6282 AppGlobals.getPackageManager().setPackageStoppedState(
6283 info.packageName, false);
6284 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006285 } catch (IllegalArgumentException e) {
6286 Slog.w(TAG, "Failed trying to unstop package "
6287 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006288 }
6289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006290 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6291 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6292 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006293 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006294 }
6295 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6296 mPersistentStartingProcesses.add(app);
6297 startProcessLocked(app, "added application", app.processName);
6298 }
6299
6300 return app;
6301 }
6302
6303 public void unhandledBack() {
6304 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6305 "unhandledBack()");
6306
6307 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006308 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006309 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006310 TAG, "Performing unhandledBack(): stack size = " + count);
6311 if (count > 1) {
6312 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006313 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006314 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6315 Binder.restoreCallingIdentity(origId);
6316 }
6317 }
6318 }
6319
6320 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6321 String name = uri.getAuthority();
6322 ContentProviderHolder cph = getContentProviderExternal(name);
6323 ParcelFileDescriptor pfd = null;
6324 if (cph != null) {
6325 // We record the binder invoker's uid in thread-local storage before
6326 // going to the content provider to open the file. Later, in the code
6327 // that handles all permissions checks, we look for this uid and use
6328 // that rather than the Activity Manager's own uid. The effect is that
6329 // we do the check against the caller's permissions even though it looks
6330 // to the content provider like the Activity Manager itself is making
6331 // the request.
6332 sCallerIdentity.set(new Identity(
6333 Binder.getCallingPid(), Binder.getCallingUid()));
6334 try {
6335 pfd = cph.provider.openFile(uri, "r");
6336 } catch (FileNotFoundException e) {
6337 // do nothing; pfd will be returned null
6338 } finally {
6339 // Ensure that whatever happens, we clean up the identity state
6340 sCallerIdentity.remove();
6341 }
6342
6343 // We've got the fd now, so we're done with the provider.
6344 removeContentProviderExternal(name);
6345 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006346 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006347 }
6348 return pfd;
6349 }
6350
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006351 // Actually is sleeping or shutting down or whatever else in the future
6352 // is an inactive state.
6353 public boolean isSleeping() {
6354 return mSleeping || mShuttingDown;
6355 }
6356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006357 public void goingToSleep() {
6358 synchronized(this) {
6359 mSleeping = true;
6360 mWindowManager.setEventDispatching(false);
6361
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006362 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006363
6364 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006365 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006366 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6367 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006368 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006369 }
6370 }
6371
Dianne Hackborn55280a92009-05-07 15:53:46 -07006372 public boolean shutdown(int timeout) {
6373 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6374 != PackageManager.PERMISSION_GRANTED) {
6375 throw new SecurityException("Requires permission "
6376 + android.Manifest.permission.SHUTDOWN);
6377 }
6378
6379 boolean timedout = false;
6380
6381 synchronized(this) {
6382 mShuttingDown = true;
6383 mWindowManager.setEventDispatching(false);
6384
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006385 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006386 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006387 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006388 while (mMainStack.mResumedActivity != null
6389 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006390 long delay = endTime - System.currentTimeMillis();
6391 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006392 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006393 timedout = true;
6394 break;
6395 }
6396 try {
6397 this.wait();
6398 } catch (InterruptedException e) {
6399 }
6400 }
6401 }
6402 }
6403
6404 mUsageStatsService.shutdown();
6405 mBatteryStatsService.shutdown();
6406
6407 return timedout;
6408 }
6409
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006410 public final void activitySlept(IBinder token) {
6411 if (localLOGV) Slog.v(
6412 TAG, "Activity slept: token=" + token);
6413
6414 ActivityRecord r = null;
6415
6416 final long origId = Binder.clearCallingIdentity();
6417
6418 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006419 r = mMainStack.isInStackLocked(token);
6420 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006421 mMainStack.activitySleptLocked(r);
6422 }
6423 }
6424
6425 Binder.restoreCallingIdentity(origId);
6426 }
6427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006428 public void wakingUp() {
6429 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006430 mWindowManager.setEventDispatching(true);
6431 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006432 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006433 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006434 }
6435 }
6436
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006437 public void stopAppSwitches() {
6438 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6439 != PackageManager.PERMISSION_GRANTED) {
6440 throw new SecurityException("Requires permission "
6441 + android.Manifest.permission.STOP_APP_SWITCHES);
6442 }
6443
6444 synchronized(this) {
6445 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6446 + APP_SWITCH_DELAY_TIME;
6447 mDidAppSwitch = false;
6448 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6449 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6450 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6451 }
6452 }
6453
6454 public void resumeAppSwitches() {
6455 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6456 != PackageManager.PERMISSION_GRANTED) {
6457 throw new SecurityException("Requires permission "
6458 + android.Manifest.permission.STOP_APP_SWITCHES);
6459 }
6460
6461 synchronized(this) {
6462 // Note that we don't execute any pending app switches... we will
6463 // let those wait until either the timeout, or the next start
6464 // activity request.
6465 mAppSwitchesAllowedTime = 0;
6466 }
6467 }
6468
6469 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6470 String name) {
6471 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6472 return true;
6473 }
6474
6475 final int perm = checkComponentPermission(
6476 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006477 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006478 if (perm == PackageManager.PERMISSION_GRANTED) {
6479 return true;
6480 }
6481
Joe Onorato8a9b2202010-02-26 18:56:32 -08006482 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006483 return false;
6484 }
6485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006486 public void setDebugApp(String packageName, boolean waitForDebugger,
6487 boolean persistent) {
6488 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6489 "setDebugApp()");
6490
6491 // Note that this is not really thread safe if there are multiple
6492 // callers into it at the same time, but that's not a situation we
6493 // care about.
6494 if (persistent) {
6495 final ContentResolver resolver = mContext.getContentResolver();
6496 Settings.System.putString(
6497 resolver, Settings.System.DEBUG_APP,
6498 packageName);
6499 Settings.System.putInt(
6500 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6501 waitForDebugger ? 1 : 0);
6502 }
6503
6504 synchronized (this) {
6505 if (!persistent) {
6506 mOrigDebugApp = mDebugApp;
6507 mOrigWaitForDebugger = mWaitForDebugger;
6508 }
6509 mDebugApp = packageName;
6510 mWaitForDebugger = waitForDebugger;
6511 mDebugTransient = !persistent;
6512 if (packageName != null) {
6513 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006514 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006515 Binder.restoreCallingIdentity(origId);
6516 }
6517 }
6518 }
6519
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006520 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6521 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6522 synchronized (this) {
6523 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6524 if (!isDebuggable) {
6525 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6526 throw new SecurityException("Process not debuggable: " + app.packageName);
6527 }
6528 }
6529 mProfileApp = processName;
6530 mProfileFile = profileFile;
6531 if (mProfileFd != null) {
6532 try {
6533 mProfileFd.close();
6534 } catch (IOException e) {
6535 }
6536 mProfileFd = null;
6537 }
6538 mProfileFd = profileFd;
6539 mProfileType = 0;
6540 mAutoStopProfiler = autoStopProfiler;
6541 }
6542 }
6543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006544 public void setAlwaysFinish(boolean enabled) {
6545 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6546 "setAlwaysFinish()");
6547
6548 Settings.System.putInt(
6549 mContext.getContentResolver(),
6550 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6551
6552 synchronized (this) {
6553 mAlwaysFinishActivities = enabled;
6554 }
6555 }
6556
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006557 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006558 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006559 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006560 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006561 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006562 }
6563 }
6564
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006565 public boolean isUserAMonkey() {
6566 // For now the fact that there is a controller implies
6567 // we have a monkey.
6568 synchronized (this) {
6569 return mController != null;
6570 }
6571 }
6572
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006573 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006574 synchronized (this) {
6575 mWatchers.register(watcher);
6576 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006577 }
6578
6579 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006580 synchronized (this) {
6581 mWatchers.unregister(watcher);
6582 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006583 }
6584
Jeff Sharkeya4620792011-05-20 15:29:23 -07006585 public void registerProcessObserver(IProcessObserver observer) {
6586 mProcessObservers.register(observer);
6587 }
6588
6589 public void unregisterProcessObserver(IProcessObserver observer) {
6590 mProcessObservers.unregister(observer);
6591 }
6592
Daniel Sandler69a48172010-06-23 16:29:36 -04006593 public void setImmersive(IBinder token, boolean immersive) {
6594 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006595 ActivityRecord r = mMainStack.isInStackLocked(token);
6596 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006597 throw new IllegalArgumentException();
6598 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006599 r.immersive = immersive;
6600 }
6601 }
6602
6603 public boolean isImmersive(IBinder token) {
6604 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006605 ActivityRecord r = mMainStack.isInStackLocked(token);
6606 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006607 throw new IllegalArgumentException();
6608 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006609 return r.immersive;
6610 }
6611 }
6612
6613 public boolean isTopActivityImmersive() {
6614 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006615 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006616 return (r != null) ? r.immersive : false;
6617 }
6618 }
6619
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006620 public final void enterSafeMode() {
6621 synchronized(this) {
6622 // It only makes sense to do this before the system is ready
6623 // and started launching other packages.
6624 if (!mSystemReady) {
6625 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006626 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006627 } catch (RemoteException e) {
6628 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006629 }
6630 }
6631 }
6632
Jeff Brownb09abc12011-01-13 21:08:27 -08006633 public final void showSafeModeOverlay() {
6634 View v = LayoutInflater.from(mContext).inflate(
6635 com.android.internal.R.layout.safe_mode, null);
6636 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6637 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6638 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6639 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6640 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6641 lp.format = v.getBackground().getOpacity();
6642 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6643 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6644 ((WindowManager)mContext.getSystemService(
6645 Context.WINDOW_SERVICE)).addView(v, lp);
6646 }
6647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006648 public void noteWakeupAlarm(IIntentSender sender) {
6649 if (!(sender instanceof PendingIntentRecord)) {
6650 return;
6651 }
6652 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6653 synchronized (stats) {
6654 if (mBatteryStatsService.isOnBattery()) {
6655 mBatteryStatsService.enforceCallingPermission();
6656 PendingIntentRecord rec = (PendingIntentRecord)sender;
6657 int MY_UID = Binder.getCallingUid();
6658 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6659 BatteryStatsImpl.Uid.Pkg pkg =
6660 stats.getPackageStatsLocked(uid, rec.key.packageName);
6661 pkg.incWakeupsLocked();
6662 }
6663 }
6664 }
6665
Dianne Hackborn64825172011-03-02 21:32:58 -08006666 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006667 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006668 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006669 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006670 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006671 // XXX Note: don't acquire main activity lock here, because the window
6672 // manager calls in with its locks held.
6673
6674 boolean killed = false;
6675 synchronized (mPidsSelfLocked) {
6676 int[] types = new int[pids.length];
6677 int worstType = 0;
6678 for (int i=0; i<pids.length; i++) {
6679 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6680 if (proc != null) {
6681 int type = proc.setAdj;
6682 types[i] = type;
6683 if (type > worstType) {
6684 worstType = type;
6685 }
6686 }
6687 }
6688
Dianne Hackborn64825172011-03-02 21:32:58 -08006689 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006690 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006691 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
6692 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07006693 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006694 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006695
6696 // If this is not a secure call, don't let it kill processes that
6697 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006698 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
6699 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006700 }
6701
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006702 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006703 for (int i=0; i<pids.length; i++) {
6704 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6705 if (proc == null) {
6706 continue;
6707 }
6708 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006709 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006710 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006711 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6712 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006713 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006714 proc.killedBackground = true;
6715 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006716 }
6717 }
6718 }
6719 return killed;
6720 }
6721
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006722 public final void startRunning(String pkg, String cls, String action,
6723 String data) {
6724 synchronized(this) {
6725 if (mStartRunning) {
6726 return;
6727 }
6728 mStartRunning = true;
6729 mTopComponent = pkg != null && cls != null
6730 ? new ComponentName(pkg, cls) : null;
6731 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6732 mTopData = data;
6733 if (!mSystemReady) {
6734 return;
6735 }
6736 }
6737
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006738 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006739 }
6740
6741 private void retrieveSettings() {
6742 final ContentResolver resolver = mContext.getContentResolver();
6743 String debugApp = Settings.System.getString(
6744 resolver, Settings.System.DEBUG_APP);
6745 boolean waitForDebugger = Settings.System.getInt(
6746 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6747 boolean alwaysFinishActivities = Settings.System.getInt(
6748 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6749
6750 Configuration configuration = new Configuration();
6751 Settings.System.getConfiguration(resolver, configuration);
6752
6753 synchronized (this) {
6754 mDebugApp = mOrigDebugApp = debugApp;
6755 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6756 mAlwaysFinishActivities = alwaysFinishActivities;
6757 // This happens before any activities are started, so we can
6758 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08006759 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006760 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006761 }
6762 }
6763
6764 public boolean testIsSystemReady() {
6765 // no need to synchronize(this) just to read & return the value
6766 return mSystemReady;
6767 }
6768
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006769 private static File getCalledPreBootReceiversFile() {
6770 File dataDir = Environment.getDataDirectory();
6771 File systemDir = new File(dataDir, "system");
6772 File fname = new File(systemDir, "called_pre_boots.dat");
6773 return fname;
6774 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006775
6776 static final int LAST_DONE_VERSION = 10000;
6777
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006778 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6779 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6780 File file = getCalledPreBootReceiversFile();
6781 FileInputStream fis = null;
6782 try {
6783 fis = new FileInputStream(file);
6784 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006785 int fvers = dis.readInt();
6786 if (fvers == LAST_DONE_VERSION) {
6787 String vers = dis.readUTF();
6788 String codename = dis.readUTF();
6789 String build = dis.readUTF();
6790 if (android.os.Build.VERSION.RELEASE.equals(vers)
6791 && android.os.Build.VERSION.CODENAME.equals(codename)
6792 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6793 int num = dis.readInt();
6794 while (num > 0) {
6795 num--;
6796 String pkg = dis.readUTF();
6797 String cls = dis.readUTF();
6798 lastDoneReceivers.add(new ComponentName(pkg, cls));
6799 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006800 }
6801 }
6802 } catch (FileNotFoundException e) {
6803 } catch (IOException e) {
6804 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6805 } finally {
6806 if (fis != null) {
6807 try {
6808 fis.close();
6809 } catch (IOException e) {
6810 }
6811 }
6812 }
6813 return lastDoneReceivers;
6814 }
6815
6816 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6817 File file = getCalledPreBootReceiversFile();
6818 FileOutputStream fos = null;
6819 DataOutputStream dos = null;
6820 try {
6821 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6822 fos = new FileOutputStream(file);
6823 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006824 dos.writeInt(LAST_DONE_VERSION);
6825 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006826 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006827 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006828 dos.writeInt(list.size());
6829 for (int i=0; i<list.size(); i++) {
6830 dos.writeUTF(list.get(i).getPackageName());
6831 dos.writeUTF(list.get(i).getClassName());
6832 }
6833 } catch (IOException e) {
6834 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6835 file.delete();
6836 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006837 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006838 if (dos != null) {
6839 try {
6840 dos.close();
6841 } catch (IOException e) {
6842 // TODO Auto-generated catch block
6843 e.printStackTrace();
6844 }
6845 }
6846 }
6847 }
6848
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006849 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006850 synchronized(this) {
6851 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006852 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006853 return;
6854 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006855
6856 // Check to see if there are any update receivers to run.
6857 if (!mDidUpdate) {
6858 if (mWaitingUpdate) {
6859 return;
6860 }
6861 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6862 List<ResolveInfo> ris = null;
6863 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006864 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006865 intent, null, 0);
6866 } catch (RemoteException e) {
6867 }
6868 if (ris != null) {
6869 for (int i=ris.size()-1; i>=0; i--) {
6870 if ((ris.get(i).activityInfo.applicationInfo.flags
6871 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6872 ris.remove(i);
6873 }
6874 }
6875 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006876
6877 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6878
6879 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006880 for (int i=0; i<ris.size(); i++) {
6881 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006882 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6883 if (lastDoneReceivers.contains(comp)) {
6884 ris.remove(i);
6885 i--;
6886 }
6887 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006888
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006889 for (int i=0; i<ris.size(); i++) {
6890 ActivityInfo ai = ris.get(i).activityInfo;
6891 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6892 doneReceivers.add(comp);
6893 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006894 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006895 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006896 finisher = new IIntentReceiver.Stub() {
6897 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006898 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006899 boolean sticky) {
6900 // The raw IIntentReceiver interface is called
6901 // with the AM lock held, so redispatch to
6902 // execute our code without the lock.
6903 mHandler.post(new Runnable() {
6904 public void run() {
6905 synchronized (ActivityManagerService.this) {
6906 mDidUpdate = true;
6907 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006908 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006909 showBootMessage(mContext.getText(
6910 R.string.android_upgrading_complete),
6911 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006912 systemReady(goingCallback);
6913 }
6914 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006915 }
6916 };
6917 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006918 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006919 broadcastIntentLocked(null, null, intent, null, finisher,
6920 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006921 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006922 mWaitingUpdate = true;
6923 }
6924 }
6925 }
6926 if (mWaitingUpdate) {
6927 return;
6928 }
6929 mDidUpdate = true;
6930 }
6931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006932 mSystemReady = true;
6933 if (!mStartRunning) {
6934 return;
6935 }
6936 }
6937
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006938 ArrayList<ProcessRecord> procsToKill = null;
6939 synchronized(mPidsSelfLocked) {
6940 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6941 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6942 if (!isAllowedWhileBooting(proc.info)){
6943 if (procsToKill == null) {
6944 procsToKill = new ArrayList<ProcessRecord>();
6945 }
6946 procsToKill.add(proc);
6947 }
6948 }
6949 }
6950
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006951 synchronized(this) {
6952 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006953 for (int i=procsToKill.size()-1; i>=0; i--) {
6954 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006955 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08006956 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006957 }
6958 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006959
6960 // Now that we have cleaned up any update processes, we
6961 // are ready to start launching real processes and know that
6962 // we won't trample on them any more.
6963 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006964 }
6965
Joe Onorato8a9b2202010-02-26 18:56:32 -08006966 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006967 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006968 SystemClock.uptimeMillis());
6969
6970 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006971 // Make sure we have no pre-ready processes sitting around.
6972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006973 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6974 ResolveInfo ri = mContext.getPackageManager()
6975 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006976 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006977 CharSequence errorMsg = null;
6978 if (ri != null) {
6979 ActivityInfo ai = ri.activityInfo;
6980 ApplicationInfo app = ai.applicationInfo;
6981 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6982 mTopAction = Intent.ACTION_FACTORY_TEST;
6983 mTopData = null;
6984 mTopComponent = new ComponentName(app.packageName,
6985 ai.name);
6986 } else {
6987 errorMsg = mContext.getResources().getText(
6988 com.android.internal.R.string.factorytest_not_system);
6989 }
6990 } else {
6991 errorMsg = mContext.getResources().getText(
6992 com.android.internal.R.string.factorytest_no_action);
6993 }
6994 if (errorMsg != null) {
6995 mTopAction = null;
6996 mTopData = null;
6997 mTopComponent = null;
6998 Message msg = Message.obtain();
6999 msg.what = SHOW_FACTORY_ERROR_MSG;
7000 msg.getData().putCharSequence("msg", errorMsg);
7001 mHandler.sendMessage(msg);
7002 }
7003 }
7004 }
7005
7006 retrieveSettings();
7007
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007008 if (goingCallback != null) goingCallback.run();
7009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007010 synchronized (this) {
7011 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7012 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007013 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07007014 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007015 if (apps != null) {
7016 int N = apps.size();
7017 int i;
7018 for (i=0; i<N; i++) {
7019 ApplicationInfo info
7020 = (ApplicationInfo)apps.get(i);
7021 if (info != null &&
7022 !info.packageName.equals("android")) {
7023 addAppLocked(info);
7024 }
7025 }
7026 }
7027 } catch (RemoteException ex) {
7028 // pm is in same process, this will never happen.
7029 }
7030 }
7031
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007032 // Start up initial activity.
7033 mBooting = true;
7034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007035 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007036 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007037 Message msg = Message.obtain();
7038 msg.what = SHOW_UID_ERROR_MSG;
7039 mHandler.sendMessage(msg);
7040 }
7041 } catch (RemoteException e) {
7042 }
7043
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007044 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007045 }
7046 }
7047
Dan Egnorb7f03672009-12-09 16:22:32 -08007048 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007049 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007050 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007051 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007052 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007053 startAppProblemLocked(app);
7054 app.stopFreezingAllLocked();
7055 return handleAppCrashLocked(app);
7056 }
7057
Dan Egnorb7f03672009-12-09 16:22:32 -08007058 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007059 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007060 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007061 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007062 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7063 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007064 startAppProblemLocked(app);
7065 app.stopFreezingAllLocked();
7066 }
7067
7068 /**
7069 * Generate a process error record, suitable for attachment to a ProcessRecord.
7070 *
7071 * @param app The ProcessRecord in which the error occurred.
7072 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7073 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007074 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007075 * @param shortMsg Short message describing the crash.
7076 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007077 * @param stackTrace Full crash stack trace, may be null.
7078 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007079 * @return Returns a fully-formed AppErrorStateInfo record.
7080 */
7081 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007082 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007083 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007085 report.condition = condition;
7086 report.processName = app.processName;
7087 report.pid = app.pid;
7088 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007089 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007090 report.shortMsg = shortMsg;
7091 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08007092 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007093
7094 return report;
7095 }
7096
Dan Egnor42471dd2010-01-07 17:25:22 -08007097 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007098 synchronized (this) {
7099 app.crashing = false;
7100 app.crashingReport = null;
7101 app.notResponding = false;
7102 app.notRespondingReport = null;
7103 if (app.anrDialog == fromDialog) {
7104 app.anrDialog = null;
7105 }
7106 if (app.waitDialog == fromDialog) {
7107 app.waitDialog = null;
7108 }
7109 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08007110 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007111 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07007112 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7113 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007114 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007115 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007116 }
7117 }
Dan Egnor42471dd2010-01-07 17:25:22 -08007118
Dan Egnorb7f03672009-12-09 16:22:32 -08007119 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007120 long now = SystemClock.uptimeMillis();
7121
7122 Long crashTime = mProcessCrashTimes.get(app.info.processName,
7123 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07007124 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007125 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08007126 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007127 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007128 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007129 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007130 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7131 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007132 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007133 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007134 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007135 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007136 }
7137 }
7138 if (!app.persistent) {
7139 // We don't want to start this process again until the user
7140 // explicitly does so... but for persistent process, we really
7141 // need to keep it running. If a persistent process is actually
7142 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08007143 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007144 app.info.processName);
7145 mBadProcesses.put(app.info.processName, app.info.uid, now);
7146 app.bad = true;
7147 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
7148 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07007149 // Don't let services in this process be restarted and potentially
7150 // annoy the user repeatedly. Unless it is persistent, since those
7151 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007152 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08007153 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007154 return false;
7155 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08007156 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007157 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007158 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007159 if (r.app == app) {
7160 // If the top running activity is from this crashing
7161 // process, then terminate it to avoid getting in a loop.
7162 Slog.w(TAG, " Force finishing activity "
7163 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08007164 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007165 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007166 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08007167 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007168 // stopped, to avoid a situation where one will get
7169 // re-start our crashing activity once it gets resumed again.
7170 index--;
7171 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007172 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007173 if (r.state == ActivityState.RESUMED
7174 || r.state == ActivityState.PAUSING
7175 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007176 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007177 Slog.w(TAG, " Force finishing activity "
7178 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007179 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007180 Activity.RESULT_CANCELED, null, "crashed");
7181 }
7182 }
7183 }
7184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007185 }
7186
7187 // Bump up the crash count of any services currently running in the proc.
7188 if (app.services.size() != 0) {
7189 // Any services running in the application need to be placed
7190 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007191 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007192 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007193 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007194 sr.crashCount++;
7195 }
7196 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007197
7198 // If the crashing process is what we consider to be the "home process" and it has been
7199 // replaced by a third-party app, clear the package preferred activities from packages
7200 // with a home activity running in the process to prevent a repeatedly crashing app
7201 // from blocking the user to manually clear the list.
7202 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7203 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7204 Iterator it = mHomeProcess.activities.iterator();
7205 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007206 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007207 if (r.isHomeActivity) {
7208 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7209 try {
7210 ActivityThread.getPackageManager()
7211 .clearPackagePreferredActivities(r.packageName);
7212 } catch (RemoteException c) {
7213 // pm is in same process, this will never happen.
7214 }
7215 }
7216 }
7217 }
7218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007219 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7220 return true;
7221 }
7222
7223 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007224 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7225 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007226 skipCurrentReceiverLocked(app);
7227 }
7228
7229 void skipCurrentReceiverLocked(ProcessRecord app) {
7230 boolean reschedule = false;
7231 BroadcastRecord r = app.curReceiver;
7232 if (r != null) {
7233 // The current broadcast is waiting for this app's receiver
7234 // to be finished. Looks like that's not going to happen, so
7235 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007236 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007237 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7238 r.resultExtras, r.resultAbort, true);
7239 reschedule = true;
7240 }
7241 r = mPendingBroadcast;
7242 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007243 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007244 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007245 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007246 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7247 r.resultExtras, r.resultAbort, true);
7248 reschedule = true;
7249 }
7250 if (reschedule) {
7251 scheduleBroadcastsLocked();
7252 }
7253 }
7254
Dan Egnor60d87622009-12-16 16:32:58 -08007255 /**
7256 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7257 * The application process will exit immediately after this call returns.
7258 * @param app object of the crashing app, null for the system server
7259 * @param crashInfo describing the exception
7260 */
7261 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007262 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007263 final String processName = app == null ? "system_server"
7264 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007265
7266 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007267 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007268 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007269 crashInfo.exceptionClassName,
7270 crashInfo.exceptionMessage,
7271 crashInfo.throwFileName,
7272 crashInfo.throwLineNumber);
7273
Jeff Sharkeya353d262011-10-28 11:12:06 -07007274 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007275
7276 crashApplication(r, crashInfo);
7277 }
7278
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007279 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007280 IBinder app,
7281 int violationMask,
7282 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007283 ProcessRecord r = findAppProcess(app, "StrictMode");
7284 if (r == null) {
7285 return;
7286 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007287
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007288 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007289 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007290 boolean logIt = true;
7291 synchronized (mAlreadyLoggedViolatedStacks) {
7292 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7293 logIt = false;
7294 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007295 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007296 // the relative pain numbers, without logging all
7297 // the stack traces repeatedly. We'd want to do
7298 // likewise in the client code, which also does
7299 // dup suppression, before the Binder call.
7300 } else {
7301 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7302 mAlreadyLoggedViolatedStacks.clear();
7303 }
7304 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7305 }
7306 }
7307 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007308 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007309 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007310 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007311
7312 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7313 AppErrorResult result = new AppErrorResult();
7314 synchronized (this) {
7315 final long origId = Binder.clearCallingIdentity();
7316
7317 Message msg = Message.obtain();
7318 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7319 HashMap<String, Object> data = new HashMap<String, Object>();
7320 data.put("result", result);
7321 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007322 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007323 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007324 msg.obj = data;
7325 mHandler.sendMessage(msg);
7326
7327 Binder.restoreCallingIdentity(origId);
7328 }
7329 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007330 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007331 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007332 }
7333
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007334 // Depending on the policy in effect, there could be a bunch of
7335 // these in quick succession so we try to batch these together to
7336 // minimize disk writes, number of dropbox entries, and maximize
7337 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007338 private void logStrictModeViolationToDropBox(
7339 ProcessRecord process,
7340 StrictMode.ViolationInfo info) {
7341 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007342 return;
7343 }
7344 final boolean isSystemApp = process == null ||
7345 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7346 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007347 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007348 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7349 final DropBoxManager dbox = (DropBoxManager)
7350 mContext.getSystemService(Context.DROPBOX_SERVICE);
7351
7352 // Exit early if the dropbox isn't configured to accept this report type.
7353 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7354
7355 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007356 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007357 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7358 synchronized (sb) {
7359 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007360 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007361 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7362 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007363 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7364 if (info.violationNumThisLoop != 0) {
7365 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7366 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007367 if (info.numAnimationsRunning != 0) {
7368 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7369 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007370 if (info.broadcastIntentAction != null) {
7371 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7372 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007373 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007374 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007375 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007376 if (info.numInstances != -1) {
7377 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7378 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007379 if (info.tags != null) {
7380 for (String tag : info.tags) {
7381 sb.append("Span-Tag: ").append(tag).append("\n");
7382 }
7383 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007384 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007385 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7386 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007387 }
7388 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007389
7390 // Only buffer up to ~64k. Various logging bits truncate
7391 // things at 128k.
7392 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007393 }
7394
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007395 // Flush immediately if the buffer's grown too large, or this
7396 // is a non-system app. Non-system apps are isolated with a
7397 // different tag & policy and not batched.
7398 //
7399 // Batching is useful during internal testing with
7400 // StrictMode settings turned up high. Without batching,
7401 // thousands of separate files could be created on boot.
7402 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007403 new Thread("Error dump: " + dropboxTag) {
7404 @Override
7405 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007406 String report;
7407 synchronized (sb) {
7408 report = sb.toString();
7409 sb.delete(0, sb.length());
7410 sb.trimToSize();
7411 }
7412 if (report.length() != 0) {
7413 dbox.addText(dropboxTag, report);
7414 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007415 }
7416 }.start();
7417 return;
7418 }
7419
7420 // System app batching:
7421 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007422 // An existing dropbox-writing thread is outstanding, so
7423 // we don't need to start it up. The existing thread will
7424 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007425 return;
7426 }
7427
7428 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7429 // (After this point, we shouldn't access AMS internal data structures.)
7430 new Thread("Error dump: " + dropboxTag) {
7431 @Override
7432 public void run() {
7433 // 5 second sleep to let stacks arrive and be batched together
7434 try {
7435 Thread.sleep(5000); // 5 seconds
7436 } catch (InterruptedException e) {}
7437
7438 String errorReport;
7439 synchronized (mStrictModeBuffer) {
7440 errorReport = mStrictModeBuffer.toString();
7441 if (errorReport.length() == 0) {
7442 return;
7443 }
7444 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7445 mStrictModeBuffer.trimToSize();
7446 }
7447 dbox.addText(dropboxTag, errorReport);
7448 }
7449 }.start();
7450 }
7451
Dan Egnor60d87622009-12-16 16:32:58 -08007452 /**
7453 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7454 * @param app object of the crashing app, null for the system server
7455 * @param tag reported by the caller
7456 * @param crashInfo describing the context of the error
7457 * @return true if the process should exit immediately (WTF is fatal)
7458 */
7459 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007460 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007461 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007462 final String processName = app == null ? "system_server"
7463 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007464
7465 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007466 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007467 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007468 tag, crashInfo.exceptionMessage);
7469
Jeff Sharkeya353d262011-10-28 11:12:06 -07007470 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007471
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007472 if (r != null && r.pid != Process.myPid() &&
7473 Settings.Secure.getInt(mContext.getContentResolver(),
7474 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007475 crashApplication(r, crashInfo);
7476 return true;
7477 } else {
7478 return false;
7479 }
7480 }
7481
7482 /**
7483 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7484 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7485 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007486 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007487 if (app == null) {
7488 return null;
7489 }
7490
7491 synchronized (this) {
7492 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7493 final int NA = apps.size();
7494 for (int ia=0; ia<NA; ia++) {
7495 ProcessRecord p = apps.valueAt(ia);
7496 if (p.thread != null && p.thread.asBinder() == app) {
7497 return p;
7498 }
7499 }
7500 }
7501
Dianne Hackborncb44d962011-03-10 17:02:27 -08007502 Slog.w(TAG, "Can't find mystery application for " + reason
7503 + " from pid=" + Binder.getCallingPid()
7504 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007505 return null;
7506 }
7507 }
7508
7509 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007510 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7511 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007512 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07007513 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7514 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007515 // Watchdog thread ends up invoking this function (with
7516 // a null ProcessRecord) to add the stack file to dropbox.
7517 // Do not acquire a lock on this (am) in such cases, as it
7518 // could cause a potential deadlock, if and when watchdog
7519 // is invoked due to unavailability of lock on am and it
7520 // would prevent watchdog from killing system_server.
7521 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007522 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007523 return;
7524 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007525 // Note: ProcessRecord 'process' is guarded by the service
7526 // instance. (notably process.pkgList, which could otherwise change
7527 // concurrently during execution of this method)
7528 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007529 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08007530 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007531 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007532 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7533 for (String pkg : process.pkgList) {
7534 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007535 try {
Dan Egnora455d192010-03-12 08:52:28 -08007536 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7537 if (pi != null) {
7538 sb.append(" v").append(pi.versionCode);
7539 if (pi.versionName != null) {
7540 sb.append(" (").append(pi.versionName).append(")");
7541 }
7542 }
7543 } catch (RemoteException e) {
7544 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007545 }
Dan Egnora455d192010-03-12 08:52:28 -08007546 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007547 }
Dan Egnora455d192010-03-12 08:52:28 -08007548 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007549 }
7550
7551 private static String processClass(ProcessRecord process) {
7552 if (process == null || process.pid == MY_PID) {
7553 return "system_server";
7554 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7555 return "system_app";
7556 } else {
7557 return "data_app";
7558 }
7559 }
7560
7561 /**
7562 * Write a description of an error (crash, WTF, ANR) to the drop box.
7563 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7564 * @param process which caused the error, null means the system server
7565 * @param activity which triggered the error, null if unknown
7566 * @param parent activity related to the error, null if unknown
7567 * @param subject line related to the error, null if absent
7568 * @param report in long form describing the error, null if absent
7569 * @param logFile to include in the report, null if none
7570 * @param crashInfo giving an application stack trace, null if absent
7571 */
7572 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07007573 ProcessRecord process, String processName, ActivityRecord activity,
7574 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007575 final String report, final File logFile,
7576 final ApplicationErrorReport.CrashInfo crashInfo) {
7577 // NOTE -- this must never acquire the ActivityManagerService lock,
7578 // otherwise the watchdog may be prevented from resetting the system.
7579
7580 final String dropboxTag = processClass(process) + "_" + eventType;
7581 final DropBoxManager dbox = (DropBoxManager)
7582 mContext.getSystemService(Context.DROPBOX_SERVICE);
7583
7584 // Exit early if the dropbox isn't configured to accept this report type.
7585 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7586
7587 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07007588 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007589 if (activity != null) {
7590 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7591 }
7592 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7593 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7594 }
7595 if (parent != null && parent != activity) {
7596 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7597 }
7598 if (subject != null) {
7599 sb.append("Subject: ").append(subject).append("\n");
7600 }
7601 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007602 if (Debug.isDebuggerConnected()) {
7603 sb.append("Debugger: Connected\n");
7604 }
Dan Egnora455d192010-03-12 08:52:28 -08007605 sb.append("\n");
7606
7607 // Do the rest in a worker thread to avoid blocking the caller on I/O
7608 // (After this point, we shouldn't access AMS internal data structures.)
7609 Thread worker = new Thread("Error dump: " + dropboxTag) {
7610 @Override
7611 public void run() {
7612 if (report != null) {
7613 sb.append(report);
7614 }
7615 if (logFile != null) {
7616 try {
7617 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7618 } catch (IOException e) {
7619 Slog.e(TAG, "Error reading " + logFile, e);
7620 }
7621 }
7622 if (crashInfo != null && crashInfo.stackTrace != null) {
7623 sb.append(crashInfo.stackTrace);
7624 }
7625
7626 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7627 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7628 if (lines > 0) {
7629 sb.append("\n");
7630
7631 // Merge several logcat streams, and take the last N lines
7632 InputStreamReader input = null;
7633 try {
7634 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7635 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7636 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7637
7638 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7639 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7640 input = new InputStreamReader(logcat.getInputStream());
7641
7642 int num;
7643 char[] buf = new char[8192];
7644 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7645 } catch (IOException e) {
7646 Slog.e(TAG, "Error running logcat", e);
7647 } finally {
7648 if (input != null) try { input.close(); } catch (IOException e) {}
7649 }
7650 }
7651
7652 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007653 }
Dan Egnora455d192010-03-12 08:52:28 -08007654 };
7655
7656 if (process == null || process.pid == MY_PID) {
7657 worker.run(); // We may be about to die -- need to run this synchronously
7658 } else {
7659 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007660 }
7661 }
7662
7663 /**
7664 * Bring up the "unexpected error" dialog box for a crashing app.
7665 * Deal with edge cases (intercepts from instrumented applications,
7666 * ActivityController, error intent receivers, that sort of thing).
7667 * @param r the application crashing
7668 * @param crashInfo describing the failure
7669 */
7670 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007671 long timeMillis = System.currentTimeMillis();
7672 String shortMsg = crashInfo.exceptionClassName;
7673 String longMsg = crashInfo.exceptionMessage;
7674 String stackTrace = crashInfo.stackTrace;
7675 if (shortMsg != null && longMsg != null) {
7676 longMsg = shortMsg + ": " + longMsg;
7677 } else if (shortMsg != null) {
7678 longMsg = shortMsg;
7679 }
7680
Dan Egnor60d87622009-12-16 16:32:58 -08007681 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007682 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007683 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007684 try {
7685 String name = r != null ? r.processName : null;
7686 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007687 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007688 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007689 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007690 + " at watcher's request");
7691 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007692 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007693 }
7694 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007695 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007696 }
7697 }
7698
7699 final long origId = Binder.clearCallingIdentity();
7700
7701 // If this process is running instrumentation, finish it.
7702 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007703 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007704 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007705 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7706 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007707 Bundle info = new Bundle();
7708 info.putString("shortMsg", shortMsg);
7709 info.putString("longMsg", longMsg);
7710 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7711 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007712 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007713 }
7714
Dan Egnor60d87622009-12-16 16:32:58 -08007715 // If we can't identify the process or it's already exceeded its crash quota,
7716 // quit right away without showing a crash dialog.
7717 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007718 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007719 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007720 }
7721
7722 Message msg = Message.obtain();
7723 msg.what = SHOW_ERROR_MSG;
7724 HashMap data = new HashMap();
7725 data.put("result", result);
7726 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007727 msg.obj = data;
7728 mHandler.sendMessage(msg);
7729
7730 Binder.restoreCallingIdentity(origId);
7731 }
7732
7733 int res = result.get();
7734
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007735 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007736 synchronized (this) {
7737 if (r != null) {
7738 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7739 SystemClock.uptimeMillis());
7740 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007741 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007742 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007743 }
7744 }
7745
7746 if (appErrorIntent != null) {
7747 try {
7748 mContext.startActivity(appErrorIntent);
7749 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007750 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007751 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007752 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007753 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007754
7755 Intent createAppErrorIntentLocked(ProcessRecord r,
7756 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7757 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007758 if (report == null) {
7759 return null;
7760 }
7761 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7762 result.setComponent(r.errorReportReceiver);
7763 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7764 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7765 return result;
7766 }
7767
Dan Egnorb7f03672009-12-09 16:22:32 -08007768 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7769 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007770 if (r.errorReportReceiver == null) {
7771 return null;
7772 }
7773
7774 if (!r.crashing && !r.notResponding) {
7775 return null;
7776 }
7777
Dan Egnorb7f03672009-12-09 16:22:32 -08007778 ApplicationErrorReport report = new ApplicationErrorReport();
7779 report.packageName = r.info.packageName;
7780 report.installerPackageName = r.errorReportReceiver.getPackageName();
7781 report.processName = r.processName;
7782 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007783 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007784
Dan Egnorb7f03672009-12-09 16:22:32 -08007785 if (r.crashing) {
7786 report.type = ApplicationErrorReport.TYPE_CRASH;
7787 report.crashInfo = crashInfo;
7788 } else if (r.notResponding) {
7789 report.type = ApplicationErrorReport.TYPE_ANR;
7790 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007791
Dan Egnorb7f03672009-12-09 16:22:32 -08007792 report.anrInfo.activity = r.notRespondingReport.tag;
7793 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7794 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007795 }
7796
Dan Egnorb7f03672009-12-09 16:22:32 -08007797 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007798 }
7799
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007800 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7801 // assume our apps are happy - lazy create the list
7802 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7803
7804 synchronized (this) {
7805
7806 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007807 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7808 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007809 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7810 // This one's in trouble, so we'll generate a report for it
7811 // crashes are higher priority (in case there's a crash *and* an anr)
7812 ActivityManager.ProcessErrorStateInfo report = null;
7813 if (app.crashing) {
7814 report = app.crashingReport;
7815 } else if (app.notResponding) {
7816 report = app.notRespondingReport;
7817 }
7818
7819 if (report != null) {
7820 if (errList == null) {
7821 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7822 }
7823 errList.add(report);
7824 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007825 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007826 " crashing = " + app.crashing +
7827 " notResponding = " + app.notResponding);
7828 }
7829 }
7830 }
7831 }
7832
7833 return errList;
7834 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007835
7836 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007837 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007838 if (currApp != null) {
7839 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7840 }
7841 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007842 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
7843 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007844 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7845 if (currApp != null) {
7846 currApp.lru = 0;
7847 }
7848 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007849 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007850 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7851 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7852 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7853 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7854 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7855 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7856 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7857 } else {
7858 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7859 }
7860 }
7861
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007862 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7863 // Lazy instantiation of list
7864 List<ActivityManager.RunningAppProcessInfo> runList = null;
7865 synchronized (this) {
7866 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007867 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7868 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007869 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7870 // Generate process state info for running application
7871 ActivityManager.RunningAppProcessInfo currApp =
7872 new ActivityManager.RunningAppProcessInfo(app.processName,
7873 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007874 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007875 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007876 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007877 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007878 if (app.persistent) {
7879 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007881 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007882 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007883 currApp.importanceReasonCode = app.adjTypeCode;
7884 if (app.adjSource instanceof ProcessRecord) {
7885 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007886 currApp.importanceReasonImportance = oomAdjToImportance(
7887 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007888 } else if (app.adjSource instanceof ActivityRecord) {
7889 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007890 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7891 }
7892 if (app.adjTarget instanceof ComponentName) {
7893 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7894 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007895 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007896 // + " lru=" + currApp.lru);
7897 if (runList == null) {
7898 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7899 }
7900 runList.add(currApp);
7901 }
7902 }
7903 }
7904 return runList;
7905 }
7906
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007907 public List<ApplicationInfo> getRunningExternalApplications() {
7908 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7909 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7910 if (runningApps != null && runningApps.size() > 0) {
7911 Set<String> extList = new HashSet<String>();
7912 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7913 if (app.pkgList != null) {
7914 for (String pkg : app.pkgList) {
7915 extList.add(pkg);
7916 }
7917 }
7918 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007919 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007920 for (String pkg : extList) {
7921 try {
7922 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7923 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7924 retList.add(info);
7925 }
7926 } catch (RemoteException e) {
7927 }
7928 }
7929 }
7930 return retList;
7931 }
7932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007933 @Override
7934 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007935 if (checkCallingPermission(android.Manifest.permission.DUMP)
7936 != PackageManager.PERMISSION_GRANTED) {
7937 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7938 + Binder.getCallingPid()
7939 + ", uid=" + Binder.getCallingUid()
7940 + " without permission "
7941 + android.Manifest.permission.DUMP);
7942 return;
7943 }
7944
7945 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007946 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007947 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007948
7949 int opti = 0;
7950 while (opti < args.length) {
7951 String opt = args[opti];
7952 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7953 break;
7954 }
7955 opti++;
7956 if ("-a".equals(opt)) {
7957 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007958 } else if ("-c".equals(opt)) {
7959 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007960 } else if ("-h".equals(opt)) {
7961 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007962 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007963 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007964 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007965 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
7966 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
7967 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007968 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007969 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
Marco Nelissen18cb2872011-11-15 11:19:53 -08007970 pw.println(" provider [COMP_SPEC]: provider client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007971 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007972 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007973 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007974 pw.println(" all: dump all activities");
7975 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007976 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007977 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7978 pw.println(" a partial substring in a component name, a");
7979 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007980 pw.println(" -a: include all available server state.");
7981 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007982 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007983 } else {
7984 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007985 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007986 }
7987
7988 // Is the caller requesting to dump a particular piece of data?
7989 if (opti < args.length) {
7990 String cmd = args[opti];
7991 opti++;
7992 if ("activities".equals(cmd) || "a".equals(cmd)) {
7993 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007994 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007995 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007996 return;
7997 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007998 String[] newArgs;
7999 String name;
8000 if (opti >= args.length) {
8001 name = null;
8002 newArgs = EMPTY_STRING_ARRAY;
8003 } else {
8004 name = args[opti];
8005 opti++;
8006 newArgs = new String[args.length - opti];
8007 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8008 args.length - opti);
8009 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008010 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008011 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008012 }
8013 return;
8014 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008015 String[] newArgs;
8016 String name;
8017 if (opti >= args.length) {
8018 name = null;
8019 newArgs = EMPTY_STRING_ARRAY;
8020 } else {
8021 name = args[opti];
8022 opti++;
8023 newArgs = new String[args.length - opti];
8024 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8025 args.length - opti);
8026 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008027 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008028 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008029 }
8030 return;
8031 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008032 String[] newArgs;
8033 String name;
8034 if (opti >= args.length) {
8035 name = null;
8036 newArgs = EMPTY_STRING_ARRAY;
8037 } else {
8038 name = args[opti];
8039 opti++;
8040 newArgs = new String[args.length - opti];
8041 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8042 args.length - opti);
8043 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008044 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008045 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008046 }
8047 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008048 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8049 synchronized (this) {
8050 dumpOomLocked(fd, pw, args, opti, true);
8051 }
8052 return;
Marco Nelissen18cb2872011-11-15 11:19:53 -08008053 } else if ("provider".equals(cmd)) {
8054 String[] newArgs;
8055 String name;
8056 if (opti >= args.length) {
8057 name = null;
8058 newArgs = EMPTY_STRING_ARRAY;
8059 } else {
8060 name = args[opti];
8061 opti++;
8062 newArgs = new String[args.length - opti];
8063 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8064 }
8065 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8066 pw.println("No providers match: " + name);
8067 pw.println("Use -h for help.");
8068 }
8069 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008070 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8071 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008072 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008073 }
8074 return;
8075 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008076 String[] newArgs;
8077 String name;
8078 if (opti >= args.length) {
8079 name = null;
8080 newArgs = EMPTY_STRING_ARRAY;
8081 } else {
8082 name = args[opti];
8083 opti++;
8084 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008085 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8086 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008087 }
8088 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8089 pw.println("No services match: " + name);
8090 pw.println("Use -h for help.");
8091 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008092 return;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008093 } else if ("package".equals(cmd)) {
8094 String[] newArgs;
8095 if (opti >= args.length) {
8096 pw.println("package: no package name specified");
8097 pw.println("Use -h for help.");
8098 return;
8099 } else {
8100 dumpPackage = args[opti];
8101 opti++;
8102 newArgs = new String[args.length - opti];
8103 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8104 args.length - opti);
8105 args = newArgs;
8106 opti = 0;
8107 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008108 } else if ("services".equals(cmd) || "s".equals(cmd)) {
8109 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008110 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008111 }
8112 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07008113 } else {
8114 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008115 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8116 pw.println("Bad activity command, or no activities match: " + cmd);
8117 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008118 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008119 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008120 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008121 }
8122
8123 // No piece of data specified, dump everything.
8124 synchronized (this) {
8125 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008126 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008127 if (needSep) {
8128 pw.println(" ");
8129 }
8130 if (dumpAll) {
8131 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008132 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008133 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008134 if (needSep) {
8135 pw.println(" ");
8136 }
8137 if (dumpAll) {
8138 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008139 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008140 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008141 if (needSep) {
8142 pw.println(" ");
8143 }
8144 if (dumpAll) {
8145 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008146 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008147 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008148 if (needSep) {
8149 pw.println(" ");
8150 }
8151 if (dumpAll) {
8152 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008153 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008154 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008155 if (needSep) {
8156 pw.println(" ");
8157 }
8158 if (dumpAll) {
8159 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008160 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008161 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008162 }
8163 }
8164
8165 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008166 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008167 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8168 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008169 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
8170 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008171 pw.println(" ");
8172 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008173 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
8174 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008175 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008176 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008177 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008178 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008179 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008180 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008181 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008182 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008183 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008184 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008185 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008186 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008187 if (mMainStack.mGoingToSleepActivities.size() > 0) {
8188 pw.println(" ");
8189 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008190 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008191 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008192 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008193 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008194 pw.println(" ");
8195 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008196 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008197 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008198 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008199
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008200 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008201 if (mMainStack.mPausingActivity != null) {
8202 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
8203 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008204 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008205 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008206 if (dumpAll) {
8207 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8208 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008209 pw.println(" mDismissKeyguardOnNextActivity: "
8210 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008211 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008212
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008213 if (mRecentTasks.size() > 0) {
8214 pw.println();
8215 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008216
8217 final int N = mRecentTasks.size();
8218 for (int i=0; i<N; i++) {
8219 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008220 if (dumpPackage != null) {
8221 if (tr.realActivity == null ||
8222 !dumpPackage.equals(tr.realActivity)) {
8223 continue;
8224 }
8225 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008226 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
8227 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008228 if (dumpAll) {
8229 mRecentTasks.get(i).dump(pw, " ");
8230 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008231 }
8232 }
8233
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008234 if (dumpAll) {
8235 pw.println(" ");
8236 pw.println(" mCurTask: " + mCurTask);
8237 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008238
8239 return true;
8240 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008241
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008242 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008243 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008244 boolean needSep = false;
8245 int numPers = 0;
8246
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008247 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8248
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008249 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008250 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8251 final int NA = procs.size();
8252 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008253 ProcessRecord r = procs.valueAt(ia);
8254 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8255 continue;
8256 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008257 if (!needSep) {
8258 pw.println(" All known processes:");
8259 needSep = true;
8260 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008261 pw.print(r.persistent ? " *PERS*" : " *APP*");
8262 pw.print(" UID "); pw.print(procs.keyAt(ia));
8263 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008264 r.dump(pw, " ");
8265 if (r.persistent) {
8266 numPers++;
8267 }
8268 }
8269 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008270 }
8271
8272 if (mLruProcesses.size() > 0) {
8273 if (needSep) pw.println(" ");
8274 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008275 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008276 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008277 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008278 needSep = true;
8279 }
8280
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008281 if (dumpAll) {
8282 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008283 boolean printed = false;
8284 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8285 ProcessRecord r = mPidsSelfLocked.valueAt(i);
8286 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8287 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008288 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008289 if (!printed) {
8290 if (needSep) pw.println(" ");
8291 needSep = true;
8292 pw.println(" PID mappings:");
8293 printed = true;
8294 }
8295 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8296 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008297 }
8298 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008299 }
8300
8301 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008302 synchronized (mPidsSelfLocked) {
8303 boolean printed = false;
8304 for (int i=0; i<mForegroundProcesses.size(); i++) {
8305 ProcessRecord r = mPidsSelfLocked.get(
8306 mForegroundProcesses.valueAt(i).pid);
8307 if (dumpPackage != null && (r == null
8308 || !dumpPackage.equals(r.info.packageName))) {
8309 continue;
8310 }
8311 if (!printed) {
8312 if (needSep) pw.println(" ");
8313 needSep = true;
8314 pw.println(" Foreground Processes:");
8315 printed = true;
8316 }
8317 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8318 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8319 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008320 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008321 }
8322
8323 if (mPersistentStartingProcesses.size() > 0) {
8324 if (needSep) pw.println(" ");
8325 needSep = true;
8326 pw.println(" Persisent processes that are starting:");
8327 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008328 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008329 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008330
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008331 if (mRemovedProcesses.size() > 0) {
8332 if (needSep) pw.println(" ");
8333 needSep = true;
8334 pw.println(" Processes that are being removed:");
8335 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008336 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008337 }
8338
8339 if (mProcessesOnHold.size() > 0) {
8340 if (needSep) pw.println(" ");
8341 needSep = true;
8342 pw.println(" Processes that are on old until the system is ready:");
8343 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008344 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008346
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008347 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008348
8349 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008350 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008351 long now = SystemClock.uptimeMillis();
8352 for (Map.Entry<String, SparseArray<Long>> procs
8353 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008354 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008355 SparseArray<Long> uids = procs.getValue();
8356 final int N = uids.size();
8357 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008358 int puid = uids.keyAt(i);
8359 ProcessRecord r = mProcessNames.get(pname, puid);
8360 if (dumpPackage != null && (r == null
8361 || !dumpPackage.equals(r.info.packageName))) {
8362 continue;
8363 }
8364 if (!printed) {
8365 if (needSep) pw.println(" ");
8366 needSep = true;
8367 pw.println(" Time since processes crashed:");
8368 printed = true;
8369 }
8370 pw.print(" Process "); pw.print(pname);
8371 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008372 pw.print(": last crashed ");
8373 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008374 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008375 }
8376 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008377 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008378
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008379 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008380 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008381 for (Map.Entry<String, SparseArray<Long>> procs
8382 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008383 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008384 SparseArray<Long> uids = procs.getValue();
8385 final int N = uids.size();
8386 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008387 int puid = uids.keyAt(i);
8388 ProcessRecord r = mProcessNames.get(pname, puid);
8389 if (dumpPackage != null && (r == null
8390 || !dumpPackage.equals(r.info.packageName))) {
8391 continue;
8392 }
8393 if (!printed) {
8394 if (needSep) pw.println(" ");
8395 needSep = true;
8396 pw.println(" Bad processes:");
8397 }
8398 pw.print(" Bad process "); pw.print(pname);
8399 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008400 pw.print(": crashed at time ");
8401 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008402 }
8403 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008405
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008406 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008407 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008408 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn50685602011-12-01 12:23:37 -08008409 if (dumpAll) {
8410 StringBuilder sb = new StringBuilder(128);
8411 sb.append(" mPreviousProcessVisibleTime: ");
8412 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
8413 pw.println(sb);
8414 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07008415 if (mHeavyWeightProcess != null) {
8416 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8417 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008418 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008419 if (dumpAll) {
8420 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008421 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008422 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008423 for (Map.Entry<String, Integer> entry
8424 : mCompatModePackages.getPackages().entrySet()) {
8425 String pkg = entry.getKey();
8426 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008427 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
8428 continue;
8429 }
8430 if (!printed) {
8431 pw.println(" mScreenCompatPackages:");
8432 printed = true;
8433 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008434 pw.print(" "); pw.print(pkg); pw.print(": ");
8435 pw.print(mode); pw.println();
8436 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008437 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008438 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008439 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8440 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8441 || mOrigWaitForDebugger) {
8442 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8443 + " mDebugTransient=" + mDebugTransient
8444 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8445 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008446 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8447 || mProfileFd != null) {
8448 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8449 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8450 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8451 + mAutoStopProfiler);
8452 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008453 if (mAlwaysFinishActivities || mController != null) {
8454 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8455 + " mController=" + mController);
8456 }
8457 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008458 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008459 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008460 + " mProcessesReady=" + mProcessesReady
8461 + " mSystemReady=" + mSystemReady);
8462 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008463 + " mBooted=" + mBooted
8464 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008465 pw.print(" mLastPowerCheckRealtime=");
8466 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8467 pw.println("");
8468 pw.print(" mLastPowerCheckUptime=");
8469 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8470 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008471 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8472 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008473 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008474 pw.println(" mNumServiceProcs=" + mNumServiceProcs
8475 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008476 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008477
8478 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008479 }
8480
Dianne Hackborn287952c2010-09-22 22:34:31 -07008481 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008482 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008483 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008484 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008485 long now = SystemClock.uptimeMillis();
8486 for (int i=0; i<mProcessesToGc.size(); i++) {
8487 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008488 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
8489 continue;
8490 }
8491 if (!printed) {
8492 if (needSep) pw.println(" ");
8493 needSep = true;
8494 pw.println(" Processes that are waiting to GC:");
8495 printed = true;
8496 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008497 pw.print(" Process "); pw.println(proc);
8498 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8499 pw.print(", last gced=");
8500 pw.print(now-proc.lastRequestedGc);
8501 pw.print(" ms ago, last lowMem=");
8502 pw.print(now-proc.lastLowMemory);
8503 pw.println(" ms ago");
8504
8505 }
8506 }
8507 return needSep;
8508 }
8509
8510 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8511 int opti, boolean dumpAll) {
8512 boolean needSep = false;
8513
8514 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008515 if (needSep) pw.println(" ");
8516 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008517 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008518 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008519 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008520 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8521 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8522 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8523 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8524 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008525 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008526 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008527 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008528 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008529 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008530 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008531
8532 if (needSep) pw.println(" ");
8533 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008534 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008535 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008536 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008537 needSep = true;
8538 }
8539
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008540 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008541
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008542 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008543 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008544 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008545 if (mHeavyWeightProcess != null) {
8546 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8547 }
8548
8549 return true;
8550 }
8551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008552 /**
8553 * There are three ways to call this:
8554 * - no service specified: dump all the services
8555 * - a flattened component name that matched an existing service was specified as the
8556 * first arg: dump that one service
8557 * - the first arg isn't the flattened component name of an existing service:
8558 * dump all services whose component contains the first arg as a substring
8559 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008560 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8561 int opti, boolean dumpAll) {
8562 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008563
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008564 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008565 synchronized (this) {
8566 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008567 services.add(r1);
8568 }
8569 }
8570 } else {
8571 ComponentName componentName = name != null
8572 ? ComponentName.unflattenFromString(name) : null;
8573 int objectId = 0;
8574 if (componentName == null) {
8575 // Not a '/' separated full component name; maybe an object ID?
8576 try {
8577 objectId = Integer.parseInt(name, 16);
8578 name = null;
8579 componentName = null;
8580 } catch (RuntimeException e) {
8581 }
8582 }
8583
8584 synchronized (this) {
8585 for (ServiceRecord r1 : mServices.values()) {
8586 if (componentName != null) {
8587 if (r1.name.equals(componentName)) {
8588 services.add(r1);
8589 }
8590 } else if (name != null) {
8591 if (r1.name.flattenToString().contains(name)) {
8592 services.add(r1);
8593 }
8594 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008595 services.add(r1);
8596 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008597 }
8598 }
8599 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008600
8601 if (services.size() <= 0) {
8602 return false;
8603 }
8604
8605 boolean needSep = false;
8606 for (int i=0; i<services.size(); i++) {
8607 if (needSep) {
8608 pw.println();
8609 }
8610 needSep = true;
8611 dumpService("", fd, pw, services.get(i), args, dumpAll);
8612 }
8613 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008614 }
8615
8616 /**
8617 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8618 * there is a thread associated with the service.
8619 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008620 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8621 final ServiceRecord r, String[] args, boolean dumpAll) {
8622 String innerPrefix = prefix + " ";
8623 synchronized (this) {
8624 pw.print(prefix); pw.print("SERVICE ");
8625 pw.print(r.shortName); pw.print(" ");
8626 pw.print(Integer.toHexString(System.identityHashCode(r)));
8627 pw.print(" pid=");
8628 if (r.app != null) pw.println(r.app.pid);
8629 else pw.println("(not running)");
8630 if (dumpAll) {
8631 r.dump(pw, innerPrefix);
8632 }
8633 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008634 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008635 pw.print(prefix); pw.println(" Client:");
8636 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008637 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008638 TransferPipe tp = new TransferPipe();
8639 try {
8640 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8641 tp.setBufferPrefix(prefix + " ");
8642 tp.go(fd);
8643 } finally {
8644 tp.kill();
8645 }
8646 } catch (IOException e) {
8647 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008648 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008649 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008650 }
8651 }
8652 }
8653
Marco Nelissen18cb2872011-11-15 11:19:53 -08008654 /**
8655 * There are three ways to call this:
8656 * - no provider specified: dump all the providers
8657 * - a flattened component name that matched an existing provider was specified as the
8658 * first arg: dump that one provider
8659 * - the first arg isn't the flattened component name of an existing provider:
8660 * dump all providers whose component contains the first arg as a substring
8661 */
8662 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8663 int opti, boolean dumpAll) {
8664 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
8665
8666 if ("all".equals(name)) {
8667 synchronized (this) {
8668 for (ContentProviderRecord r1 : mProvidersByClass.values()) {
8669 providers.add(r1);
8670 }
8671 }
8672 } else {
8673 ComponentName componentName = name != null
8674 ? ComponentName.unflattenFromString(name) : null;
8675 int objectId = 0;
8676 if (componentName == null) {
8677 // Not a '/' separated full component name; maybe an object ID?
8678 try {
8679 objectId = Integer.parseInt(name, 16);
8680 name = null;
8681 componentName = null;
8682 } catch (RuntimeException e) {
8683 }
8684 }
8685
8686 synchronized (this) {
8687 for (ContentProviderRecord r1 : mProvidersByClass.values()) {
8688 if (componentName != null) {
8689 if (r1.name.equals(componentName)) {
8690 providers.add(r1);
8691 }
8692 } else if (name != null) {
8693 if (r1.name.flattenToString().contains(name)) {
8694 providers.add(r1);
8695 }
8696 } else if (System.identityHashCode(r1) == objectId) {
8697 providers.add(r1);
8698 }
8699 }
8700 }
8701 }
8702
8703 if (providers.size() <= 0) {
8704 return false;
8705 }
8706
8707 boolean needSep = false;
8708 for (int i=0; i<providers.size(); i++) {
8709 if (needSep) {
8710 pw.println();
8711 }
8712 needSep = true;
8713 dumpProvider("", fd, pw, providers.get(i), args, dumpAll);
8714 }
8715 return true;
8716 }
8717
8718 /**
8719 * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider if
8720 * there is a thread associated with the provider.
8721 */
8722 private void dumpProvider(String prefix, FileDescriptor fd, PrintWriter pw,
8723 final ContentProviderRecord r, String[] args, boolean dumpAll) {
8724 String innerPrefix = prefix + " ";
8725 synchronized (this) {
8726 pw.print(prefix); pw.print("PROVIDER ");
8727 pw.print(r);
8728 pw.print(" pid=");
8729 if (r.proc != null) pw.println(r.proc.pid);
8730 else pw.println("(not running)");
8731 if (dumpAll) {
8732 r.dump(pw, innerPrefix);
8733 }
8734 }
8735 if (r.proc != null && r.proc.thread != null) {
8736 pw.println(" Client:");
8737 pw.flush();
8738 try {
8739 TransferPipe tp = new TransferPipe();
8740 try {
8741 r.proc.thread.dumpProvider(
8742 tp.getWriteFd().getFileDescriptor(), r.provider.asBinder(), args);
8743 tp.setBufferPrefix(" ");
8744 // Short timeout, since blocking here can
8745 // deadlock with the application.
8746 tp.go(fd, 2000);
8747 } finally {
8748 tp.kill();
8749 }
8750 } catch (IOException ex) {
8751 pw.println(" Failure while dumping the provider: " + ex);
8752 } catch (RemoteException ex) {
8753 pw.println(" Got a RemoteException while dumping the service");
8754 }
8755 }
8756 }
8757
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008758 static class ItemMatcher {
8759 ArrayList<ComponentName> components;
8760 ArrayList<String> strings;
8761 ArrayList<Integer> objects;
8762 boolean all;
8763
8764 ItemMatcher() {
8765 all = true;
8766 }
8767
8768 void build(String name) {
8769 ComponentName componentName = ComponentName.unflattenFromString(name);
8770 if (componentName != null) {
8771 if (components == null) {
8772 components = new ArrayList<ComponentName>();
8773 }
8774 components.add(componentName);
8775 all = false;
8776 } else {
8777 int objectId = 0;
8778 // Not a '/' separated full component name; maybe an object ID?
8779 try {
8780 objectId = Integer.parseInt(name, 16);
8781 if (objects == null) {
8782 objects = new ArrayList<Integer>();
8783 }
8784 objects.add(objectId);
8785 all = false;
8786 } catch (RuntimeException e) {
8787 // Not an integer; just do string match.
8788 if (strings == null) {
8789 strings = new ArrayList<String>();
8790 }
8791 strings.add(name);
8792 all = false;
8793 }
8794 }
8795 }
8796
8797 int build(String[] args, int opti) {
8798 for (; opti<args.length; opti++) {
8799 String name = args[opti];
8800 if ("--".equals(name)) {
8801 return opti+1;
8802 }
8803 build(name);
8804 }
8805 return opti;
8806 }
8807
8808 boolean match(Object object, ComponentName comp) {
8809 if (all) {
8810 return true;
8811 }
8812 if (components != null) {
8813 for (int i=0; i<components.size(); i++) {
8814 if (components.get(i).equals(comp)) {
8815 return true;
8816 }
8817 }
8818 }
8819 if (objects != null) {
8820 for (int i=0; i<objects.size(); i++) {
8821 if (System.identityHashCode(object) == objects.get(i)) {
8822 return true;
8823 }
8824 }
8825 }
8826 if (strings != null) {
8827 String flat = comp.flattenToString();
8828 for (int i=0; i<strings.size(); i++) {
8829 if (flat.contains(strings.get(i))) {
8830 return true;
8831 }
8832 }
8833 }
8834 return false;
8835 }
8836 }
8837
Dianne Hackborn625ac272010-09-17 18:29:22 -07008838 /**
8839 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008840 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008841 * - the cmd arg isn't the flattened component name of an existing activity:
8842 * dump all activity whose component contains the cmd as a substring
8843 * - A hex number of the ActivityRecord object instance.
8844 */
8845 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8846 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008847 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008848
8849 if ("all".equals(name)) {
8850 synchronized (this) {
8851 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008852 activities.add(r1);
8853 }
8854 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008855 } else if ("top".equals(name)) {
8856 synchronized (this) {
8857 final int N = mMainStack.mHistory.size();
8858 if (N > 0) {
8859 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8860 }
8861 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008862 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008863 ItemMatcher matcher = new ItemMatcher();
8864 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008865
8866 synchronized (this) {
8867 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008868 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008869 activities.add(r1);
8870 }
8871 }
8872 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008873 }
8874
8875 if (activities.size() <= 0) {
8876 return false;
8877 }
8878
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008879 String[] newArgs = new String[args.length - opti];
8880 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8881
Dianne Hackborn30d71892010-12-11 10:37:55 -08008882 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008883 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008884 for (int i=activities.size()-1; i>=0; i--) {
8885 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008886 if (needSep) {
8887 pw.println();
8888 }
8889 needSep = true;
8890 synchronized (this) {
8891 if (lastTask != r.task) {
8892 lastTask = r.task;
8893 pw.print("TASK "); pw.print(lastTask.affinity);
8894 pw.print(" id="); pw.println(lastTask.taskId);
8895 if (dumpAll) {
8896 lastTask.dump(pw, " ");
8897 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008898 }
8899 }
8900 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008901 }
8902 return true;
8903 }
8904
8905 /**
8906 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8907 * there is a thread associated with the activity.
8908 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008909 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008910 final ActivityRecord r, String[] args, boolean dumpAll) {
8911 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008912 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008913 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8914 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8915 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008916 if (r.app != null) pw.println(r.app.pid);
8917 else pw.println("(not running)");
8918 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008919 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008920 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008921 }
8922 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008923 // flush anything that is already in the PrintWriter since the thread is going
8924 // to write to the file descriptor directly
8925 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008926 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008927 TransferPipe tp = new TransferPipe();
8928 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08008929 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
8930 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008931 tp.go(fd);
8932 } finally {
8933 tp.kill();
8934 }
8935 } catch (IOException e) {
8936 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008937 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008938 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008939 }
8940 }
8941 }
8942
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008943 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008944 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008945 boolean needSep = false;
8946
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008947 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008948 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008949 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008950 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008951 Iterator it = mRegisteredReceivers.values().iterator();
8952 while (it.hasNext()) {
8953 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008954 if (dumpPackage != null && (r.app == null ||
8955 !dumpPackage.equals(r.app.info.packageName))) {
8956 continue;
8957 }
8958 if (!printed) {
8959 pw.println(" Registered Receivers:");
8960 needSep = true;
8961 printed = true;
8962 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008963 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008964 r.dump(pw, " ");
8965 }
8966 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008967
8968 if (mReceiverResolver.dump(pw, needSep ?
8969 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
8970 " ", dumpPackage, false)) {
8971 needSep = true;
8972 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008973 }
8974
8975 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8976 || mPendingBroadcast != null) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008977 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008978 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008979 BroadcastRecord br = mParallelBroadcasts.get(i);
8980 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8981 continue;
8982 }
8983 if (!printed) {
8984 if (needSep) {
8985 pw.println();
8986 }
8987 needSep = true;
8988 pw.println(" Active broadcasts:");
8989 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008990 pw.println(" Broadcast #" + i + ":");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008991 br.dump(pw, " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008992 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008993 printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008994 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008995 BroadcastRecord br = mOrderedBroadcasts.get(i);
8996 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8997 continue;
8998 }
8999 if (!printed) {
9000 if (needSep) {
9001 pw.println();
9002 }
9003 needSep = true;
9004 pw.println(" Active ordered broadcasts:");
9005 }
9006 pw.println(" Ordered Broadcast #" + i + ":");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009007 mOrderedBroadcasts.get(i).dump(pw, " ");
9008 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009009 if (dumpPackage == null || (mPendingBroadcast != null
9010 && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
9011 if (needSep) {
9012 pw.println();
9013 }
9014 pw.println(" Pending broadcast:");
9015 if (mPendingBroadcast != null) {
9016 mPendingBroadcast.dump(pw, " ");
9017 } else {
9018 pw.println(" (null)");
9019 }
9020 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009021 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009022 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009023
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009024 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009025 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
9026 BroadcastRecord r = mBroadcastHistory[i];
9027 if (r == null) {
9028 break;
9029 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009030 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
9031 continue;
9032 }
9033 if (!printed) {
9034 if (needSep) {
9035 pw.println();
9036 }
9037 needSep = true;
9038 pw.println(" Historical broadcasts:");
9039 printed = true;
9040 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009041 if (dumpAll) {
9042 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
9043 r.dump(pw, " ");
9044 } else {
9045 if (i >= 50) {
9046 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08009047 break;
9048 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009049 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08009050 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009051 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009052 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009053
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009054 if (mStickyBroadcasts != null && dumpPackage == null) {
9055 if (needSep) {
9056 pw.println();
9057 }
9058 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009059 pw.println(" Sticky broadcasts:");
9060 StringBuilder sb = new StringBuilder(128);
9061 for (Map.Entry<String, ArrayList<Intent>> ent
9062 : mStickyBroadcasts.entrySet()) {
9063 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009064 if (dumpAll) {
9065 pw.println(":");
9066 ArrayList<Intent> intents = ent.getValue();
9067 final int N = intents.size();
9068 for (int i=0; i<N; i++) {
9069 sb.setLength(0);
9070 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009071 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009072 pw.println(sb.toString());
9073 Bundle bundle = intents.get(i).getExtras();
9074 if (bundle != null) {
9075 pw.print(" ");
9076 pw.println(bundle.toString());
9077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009078 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009079 } else {
9080 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009081 }
9082 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009083 needSep = true;
9084 }
9085
9086 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009087 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009088 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009089 pw.println(" mHandler:");
9090 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009091 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009092 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009093
9094 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009095 }
9096
Marco Nelissen18cb2872011-11-15 11:19:53 -08009097 /**
9098 * Prints a list of ServiceRecords (dumpsys activity services)
9099 */
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009100 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009101 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009102 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009103
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009104 ItemMatcher matcher = new ItemMatcher();
9105 matcher.build(args, opti);
9106
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009107 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
9108 if (mServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009109 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009110 long nowReal = SystemClock.elapsedRealtime();
9111 Iterator<ServiceRecord> it = mServices.values().iterator();
9112 needSep = false;
9113 while (it.hasNext()) {
9114 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009115 if (!matcher.match(r, r.name)) {
9116 continue;
9117 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009118 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9119 continue;
9120 }
9121 if (!printed) {
9122 pw.println(" Active services:");
9123 printed = true;
9124 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009125 if (needSep) {
9126 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009127 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009128 pw.print(" * "); pw.println(r);
9129 if (dumpAll) {
9130 r.dump(pw, " ");
9131 needSep = true;
9132 } else {
9133 pw.print(" app="); pw.println(r.app);
9134 pw.print(" created=");
9135 TimeUtils.formatDuration(r.createTime, nowReal, pw);
9136 pw.print(" started="); pw.print(r.startRequested);
9137 pw.print(" connections="); pw.println(r.connections.size());
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009138 if (r.connections.size() > 0) {
9139 pw.println(" Connections:");
9140 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
9141 for (int i=0; i<clist.size(); i++) {
9142 ConnectionRecord conn = clist.get(i);
9143 pw.print(" ");
9144 pw.print(conn.binding.intent.intent.getIntent().toShortString(
9145 false, false, false));
9146 pw.print(" -> ");
9147 ProcessRecord proc = conn.binding.client;
9148 pw.println(proc != null ? proc.toShortString() : "null");
9149 }
9150 }
9151 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009152 }
9153 if (dumpClient && r.app != null && r.app.thread != null) {
9154 pw.println(" Client:");
9155 pw.flush();
9156 try {
9157 TransferPipe tp = new TransferPipe();
9158 try {
9159 r.app.thread.dumpService(
9160 tp.getWriteFd().getFileDescriptor(), r, args);
9161 tp.setBufferPrefix(" ");
9162 // Short timeout, since blocking here can
9163 // deadlock with the application.
9164 tp.go(fd, 2000);
9165 } finally {
9166 tp.kill();
9167 }
9168 } catch (IOException e) {
9169 pw.println(" Failure while dumping the service: " + e);
9170 } catch (RemoteException e) {
9171 pw.println(" Got a RemoteException while dumping the service");
9172 }
9173 needSep = true;
9174 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009175 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009176 needSep = printed;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009178
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009179 if (mPendingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009180 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009181 for (int i=0; i<mPendingServices.size(); i++) {
9182 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009183 if (!matcher.match(r, r.name)) {
9184 continue;
9185 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009186 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9187 continue;
9188 }
9189 if (!printed) {
9190 if (needSep) pw.println(" ");
9191 needSep = true;
9192 pw.println(" Pending services:");
9193 printed = true;
9194 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009195 pw.print(" * Pending "); pw.println(r);
9196 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009197 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009198 needSep = true;
9199 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009200
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009201 if (mRestartingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009202 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009203 for (int i=0; i<mRestartingServices.size(); i++) {
9204 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009205 if (!matcher.match(r, r.name)) {
9206 continue;
9207 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009208 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9209 continue;
9210 }
9211 if (!printed) {
9212 if (needSep) pw.println(" ");
9213 needSep = true;
9214 pw.println(" Restarting services:");
9215 printed = true;
9216 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009217 pw.print(" * Restarting "); pw.println(r);
9218 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009219 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009220 needSep = true;
9221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009222
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009223 if (mStoppingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009224 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009225 for (int i=0; i<mStoppingServices.size(); i++) {
9226 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009227 if (!matcher.match(r, r.name)) {
9228 continue;
9229 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009230 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9231 continue;
9232 }
9233 if (!printed) {
9234 if (needSep) pw.println(" ");
9235 needSep = true;
9236 pw.println(" Stopping services:");
9237 printed = true;
9238 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009239 pw.print(" * Stopping "); pw.println(r);
9240 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009241 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009242 needSep = true;
9243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009244
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009245 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009246 if (mServiceConnections.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009247 boolean printed = false;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009248 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009249 = mServiceConnections.values().iterator();
9250 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009251 ArrayList<ConnectionRecord> r = it.next();
9252 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009253 ConnectionRecord cr = r.get(i);
9254 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9255 continue;
9256 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009257 if (dumpPackage != null && (cr.binding.client == null
9258 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9259 continue;
9260 }
9261 if (!printed) {
9262 if (needSep) pw.println(" ");
9263 needSep = true;
9264 pw.println(" Connection bindings to services:");
9265 printed = true;
9266 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009267 pw.print(" * "); pw.println(cr);
9268 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009269 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009270 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009271 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009272 }
9273 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009274
9275 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009276 }
9277
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009278 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009279 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009280 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009281
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009282 ItemMatcher matcher = new ItemMatcher();
9283 matcher.build(args, opti);
9284
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009285 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9286 if (mProvidersByClass.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009287 boolean printed = false;
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009288 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009289 = mProvidersByClass.entrySet().iterator();
9290 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009291 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009292 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009293 ComponentName comp = e.getKey();
9294 String cls = comp.getClassName();
9295 int end = cls.lastIndexOf('.');
9296 if (end > 0 && end < (cls.length()-2)) {
9297 cls = cls.substring(end+1);
9298 }
9299 if (!matcher.match(r, comp)) {
9300 continue;
9301 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009302 if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) {
9303 continue;
9304 }
9305 if (!printed) {
9306 if (needSep) pw.println(" ");
9307 needSep = true;
9308 pw.println(" Published content providers (by class):");
9309 printed = true;
9310 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009311 pw.print(" * "); pw.print(cls); pw.print(" (");
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009312 pw.print(comp.flattenToShortString()); pw.println(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009313 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009314 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009315 } else {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009316 if (r.proc != null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009317 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009318 } else {
9319 pw.println();
9320 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009321 if (r.clients.size() > 0) {
9322 pw.println(" Clients:");
9323 for (ProcessRecord cproc : r.clients) {
9324 pw.print(" - "); pw.println(cproc);
9325 }
9326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009328 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009329 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009330
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009331 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009332 if (mProvidersByName.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009333 boolean printed = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -07009334 Iterator<Map.Entry<String, ContentProviderRecord>> it
9335 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009336 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009337 Map.Entry<String, ContentProviderRecord> e = it.next();
9338 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009339 if (!matcher.match(r, r.name)) {
9340 continue;
9341 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009342 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9343 continue;
9344 }
9345 if (!printed) {
9346 if (needSep) pw.println(" ");
9347 needSep = true;
9348 pw.println(" Authority to provider mappings:");
9349 printed = true;
9350 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009351 pw.print(" "); pw.print(e.getKey()); pw.println(":");
9352 pw.print(" "); pw.println(r);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009353 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009355 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009356
9357 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009358 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009359 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009360 ContentProviderRecord r = mLaunchingProviders.get(i);
9361 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9362 continue;
9363 }
9364 if (!printed) {
9365 if (needSep) pw.println(" ");
9366 needSep = true;
9367 pw.println(" Launching content providers:");
9368 printed = true;
9369 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009370 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009371 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009372 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009373 }
9374
9375 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009376 if (needSep) pw.println();
9377 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009378 pw.println("Granted Uri Permissions:");
9379 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9380 int uid = mGrantedUriPermissions.keyAt(i);
9381 HashMap<Uri, UriPermission> perms
9382 = mGrantedUriPermissions.valueAt(i);
9383 pw.print(" * UID "); pw.print(uid);
9384 pw.println(" holds:");
9385 for (UriPermission perm : perms.values()) {
9386 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009387 if (dumpAll) {
9388 perm.dump(pw, " ");
9389 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009390 }
9391 }
9392 needSep = true;
9393 }
9394
9395 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009396 }
9397
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009398 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009399 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009400 boolean needSep = false;
9401
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009402 if (mIntentSenderRecords.size() > 0) {
9403 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009404 Iterator<WeakReference<PendingIntentRecord>> it
9405 = mIntentSenderRecords.values().iterator();
9406 while (it.hasNext()) {
9407 WeakReference<PendingIntentRecord> ref = it.next();
9408 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009409 if (dumpPackage != null && (rec == null
9410 || !dumpPackage.equals(rec.key.packageName))) {
9411 continue;
9412 }
9413 if (!printed) {
9414 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9415 printed = true;
9416 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009417 needSep = true;
9418 if (rec != null) {
9419 pw.print(" * "); pw.println(rec);
9420 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009421 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009422 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009423 } else {
9424 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009425 }
9426 }
9427 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009428
9429 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009430 }
9431
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009432 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009433 String prefix, String label, boolean complete, boolean brief, boolean client,
9434 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009435 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009436 boolean needNL = false;
9437 final String innerPrefix = prefix + " ";
9438 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009439 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009440 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009441 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9442 continue;
9443 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07009444 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009445 if (needNL) {
9446 pw.println(" ");
9447 needNL = false;
9448 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009449 if (lastTask != r.task) {
9450 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009451 pw.print(prefix);
9452 pw.print(full ? "* " : " ");
9453 pw.println(lastTask);
9454 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009455 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009456 } else if (complete) {
9457 // Complete + brief == give a summary. Isn't that obvious?!?
9458 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009459 pw.print(prefix); pw.print(" ");
9460 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009461 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009462 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009463 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009464 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
9465 pw.print(" #"); pw.print(i); pw.print(": ");
9466 pw.println(r);
9467 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009468 r.dump(pw, innerPrefix);
9469 } else if (complete) {
9470 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009471 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009472 if (r.app != null) {
9473 pw.print(innerPrefix); pw.println(r.app);
9474 }
9475 }
9476 if (client && r.app != null && r.app.thread != null) {
9477 // flush anything that is already in the PrintWriter since the thread is going
9478 // to write to the file descriptor directly
9479 pw.flush();
9480 try {
9481 TransferPipe tp = new TransferPipe();
9482 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009483 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9484 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009485 // Short timeout, since blocking here can
9486 // deadlock with the application.
9487 tp.go(fd, 2000);
9488 } finally {
9489 tp.kill();
9490 }
9491 } catch (IOException e) {
9492 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9493 } catch (RemoteException e) {
9494 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9495 }
9496 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009498 }
9499 }
9500
Dianne Hackborn09c916b2009-12-08 14:50:51 -08009501 private static String buildOomTag(String prefix, String space, int val, int base) {
9502 if (val == base) {
9503 if (space == null) return prefix;
9504 return prefix + " ";
9505 }
9506 return prefix + "+" + Integer.toString(val-base);
9507 }
9508
9509 private static final int dumpProcessList(PrintWriter pw,
9510 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009511 String prefix, String normalLabel, String persistentLabel,
9512 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009513 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009514 final int N = list.size()-1;
9515 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009516 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009517 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9518 continue;
9519 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009520 pw.println(String.format("%s%s #%2d: %s",
9521 prefix, (r.persistent ? persistentLabel : normalLabel),
9522 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009523 if (r.persistent) {
9524 numPers++;
9525 }
9526 }
9527 return numPers;
9528 }
9529
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009530 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07009531 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009532 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009533 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009534
Dianne Hackborn905577f2011-09-07 18:31:28 -07009535 ArrayList<Pair<ProcessRecord, Integer>> list
9536 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9537 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009538 ProcessRecord r = origList.get(i);
9539 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9540 continue;
9541 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07009542 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9543 }
9544
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009545 if (list.size() <= 0) {
9546 return false;
9547 }
9548
Dianne Hackborn905577f2011-09-07 18:31:28 -07009549 Comparator<Pair<ProcessRecord, Integer>> comparator
9550 = new Comparator<Pair<ProcessRecord, Integer>>() {
9551 @Override
9552 public int compare(Pair<ProcessRecord, Integer> object1,
9553 Pair<ProcessRecord, Integer> object2) {
9554 if (object1.first.setAdj != object2.first.setAdj) {
9555 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9556 }
9557 if (object1.second.intValue() != object2.second.intValue()) {
9558 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9559 }
9560 return 0;
9561 }
9562 };
9563
9564 Collections.sort(list, comparator);
9565
Dianne Hackborn287952c2010-09-22 22:34:31 -07009566 final long curRealtime = SystemClock.elapsedRealtime();
9567 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9568 final long curUptime = SystemClock.uptimeMillis();
9569 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9570
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009571 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07009572 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009573 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009574 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009575 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009576 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9577 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009578 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9579 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009580 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9581 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009582 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9583 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009584 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009585 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009586 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9587 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9588 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9589 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9590 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9591 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9592 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9593 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009594 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9595 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009596 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9597 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009598 } else {
9599 oomAdj = Integer.toString(r.setAdj);
9600 }
9601 String schedGroup;
9602 switch (r.setSchedGroup) {
9603 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9604 schedGroup = "B";
9605 break;
9606 case Process.THREAD_GROUP_DEFAULT:
9607 schedGroup = "F";
9608 break;
9609 default:
9610 schedGroup = Integer.toString(r.setSchedGroup);
9611 break;
9612 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009613 String foreground;
9614 if (r.foregroundActivities) {
9615 foreground = "A";
9616 } else if (r.foregroundServices) {
9617 foreground = "S";
9618 } else {
9619 foreground = " ";
9620 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009621 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009622 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009623 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9624 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009625 if (r.adjSource != null || r.adjTarget != null) {
9626 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009627 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009628 if (r.adjTarget instanceof ComponentName) {
9629 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9630 } else if (r.adjTarget != null) {
9631 pw.print(r.adjTarget.toString());
9632 } else {
9633 pw.print("{null}");
9634 }
9635 pw.print("<=");
9636 if (r.adjSource instanceof ProcessRecord) {
9637 pw.print("Proc{");
9638 pw.print(((ProcessRecord)r.adjSource).toShortString());
9639 pw.println("}");
9640 } else if (r.adjSource != null) {
9641 pw.println(r.adjSource.toString());
9642 } else {
9643 pw.println("{null}");
9644 }
9645 }
9646 if (inclDetails) {
9647 pw.print(prefix);
9648 pw.print(" ");
9649 pw.print("oom: max="); pw.print(r.maxAdj);
9650 pw.print(" hidden="); pw.print(r.hiddenAdj);
9651 pw.print(" curRaw="); pw.print(r.curRawAdj);
9652 pw.print(" setRaw="); pw.print(r.setRawAdj);
9653 pw.print(" cur="); pw.print(r.curAdj);
9654 pw.print(" set="); pw.println(r.setAdj);
9655 pw.print(prefix);
9656 pw.print(" ");
9657 pw.print("keeping="); pw.print(r.keeping);
9658 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009659 pw.print(" empty="); pw.print(r.empty);
9660 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009661
9662 if (!r.keeping) {
9663 if (r.lastWakeTime != 0) {
9664 long wtime;
9665 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9666 synchronized (stats) {
9667 wtime = stats.getProcessWakeTime(r.info.uid,
9668 r.pid, curRealtime);
9669 }
9670 long timeUsed = wtime - r.lastWakeTime;
9671 pw.print(prefix);
9672 pw.print(" ");
9673 pw.print("keep awake over ");
9674 TimeUtils.formatDuration(realtimeSince, pw);
9675 pw.print(" used ");
9676 TimeUtils.formatDuration(timeUsed, pw);
9677 pw.print(" (");
9678 pw.print((timeUsed*100)/realtimeSince);
9679 pw.println("%)");
9680 }
9681 if (r.lastCpuTime != 0) {
9682 long timeUsed = r.curCpuTime - r.lastCpuTime;
9683 pw.print(prefix);
9684 pw.print(" ");
9685 pw.print("run cpu over ");
9686 TimeUtils.formatDuration(uptimeSince, pw);
9687 pw.print(" used ");
9688 TimeUtils.formatDuration(timeUsed, pw);
9689 pw.print(" (");
9690 pw.print((timeUsed*100)/uptimeSince);
9691 pw.println("%)");
9692 }
9693 }
9694 }
9695 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009696 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009697 }
9698
Dianne Hackbornb437e092011-08-05 17:50:29 -07009699 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009700 ArrayList<ProcessRecord> procs;
9701 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009702 if (args != null && args.length > start
9703 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009704 procs = new ArrayList<ProcessRecord>();
9705 int pid = -1;
9706 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009707 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009708 } catch (NumberFormatException e) {
9709
9710 }
9711 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9712 ProcessRecord proc = mLruProcesses.get(i);
9713 if (proc.pid == pid) {
9714 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009715 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009716 procs.add(proc);
9717 }
9718 }
9719 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009720 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009721 return null;
9722 }
9723 } else {
9724 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9725 }
9726 }
9727 return procs;
9728 }
9729
9730 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9731 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009732 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009733 if (procs == null) {
9734 return;
9735 }
9736
9737 long uptime = SystemClock.uptimeMillis();
9738 long realtime = SystemClock.elapsedRealtime();
9739 pw.println("Applications Graphics Acceleration Info:");
9740 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9741
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009742 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9743 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009744 if (r.thread != null) {
9745 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9746 pw.flush();
9747 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009748 TransferPipe tp = new TransferPipe();
9749 try {
9750 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9751 tp.go(fd);
9752 } finally {
9753 tp.kill();
9754 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009755 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009756 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009757 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009758 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009759 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009760 pw.flush();
9761 }
9762 }
9763 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009764 }
9765
Jeff Brown6754ba22011-12-14 20:20:01 -08009766 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9767 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9768 if (procs == null) {
9769 return;
9770 }
9771
9772 pw.println("Applications Database Info:");
9773
9774 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9775 ProcessRecord r = procs.get(i);
9776 if (r.thread != null) {
9777 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
9778 pw.flush();
9779 try {
9780 TransferPipe tp = new TransferPipe();
9781 try {
9782 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
9783 tp.go(fd);
9784 } finally {
9785 tp.kill();
9786 }
9787 } catch (IOException e) {
9788 pw.println("Failure while dumping the app: " + r);
9789 pw.flush();
9790 } catch (RemoteException e) {
9791 pw.println("Got a RemoteException while dumping the app " + r);
9792 pw.flush();
9793 }
9794 }
9795 }
9796 }
9797
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009798 final static class MemItem {
9799 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009800 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009801 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009802 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009803 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009804
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009805 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009806 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009807 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009808 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009809 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009810 }
9811 }
9812
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009813 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -07009814 boolean sort) {
9815 if (sort) {
9816 Collections.sort(items, new Comparator<MemItem>() {
9817 @Override
9818 public int compare(MemItem lhs, MemItem rhs) {
9819 if (lhs.pss < rhs.pss) {
9820 return 1;
9821 } else if (lhs.pss > rhs.pss) {
9822 return -1;
9823 }
9824 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009825 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009826 });
9827 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009828
9829 for (int i=0; i<items.size(); i++) {
9830 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009831 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009832 if (mi.subitems != null) {
9833 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9834 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009835 }
9836 }
9837
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009838 // These are in KB.
9839 static final long[] DUMP_MEM_BUCKETS = new long[] {
9840 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9841 120*1024, 160*1024, 200*1024,
9842 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9843 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9844 };
9845
Dianne Hackborn672342c2011-11-29 11:29:02 -08009846 static final void appendMemBucket(StringBuilder out, long memKB, String label,
9847 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009848 int start = label.lastIndexOf('.');
9849 if (start >= 0) start++;
9850 else start = 0;
9851 int end = label.length();
9852 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9853 if (DUMP_MEM_BUCKETS[i] >= memKB) {
9854 long bucket = DUMP_MEM_BUCKETS[i]/1024;
9855 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -08009856 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009857 out.append(label, start, end);
9858 return;
9859 }
9860 }
9861 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08009862 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009863 out.append(label, start, end);
9864 }
9865
9866 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9867 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9868 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9869 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9870 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9871 };
9872 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9873 "System", "Persistent", "Foreground",
9874 "Visible", "Perceptible", "Heavy Weight",
9875 "Backup", "A Services", "Home", "Previous",
9876 "B Services", "Background"
9877 };
9878
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009879 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009880 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -08009881 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009882 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009883 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009884
9885 int opti = 0;
9886 while (opti < args.length) {
9887 String opt = args[opti];
9888 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9889 break;
9890 }
9891 opti++;
9892 if ("-a".equals(opt)) {
9893 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009894 } else if ("--oom".equals(opt)) {
9895 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009896 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009897 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009898 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009899 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009900 pw.println("If [process] is specified it can be the name or ");
9901 pw.println("pid of a specific process to dump.");
9902 return;
9903 } else {
9904 pw.println("Unknown argument: " + opt + "; use -h for help");
9905 }
9906 }
9907
9908 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009909 if (procs == null) {
9910 return;
9911 }
9912
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009913 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009914 long uptime = SystemClock.uptimeMillis();
9915 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009916
9917 if (procs.size() == 1 || isCheckinRequest) {
9918 dumpAll = true;
9919 }
9920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009921 if (isCheckinRequest) {
9922 // short checkin version
9923 pw.println(uptime + "," + realtime);
9924 pw.flush();
9925 } else {
9926 pw.println("Applications Memory Usage (kB):");
9927 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9928 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009929
Dianne Hackbornb437e092011-08-05 17:50:29 -07009930 String[] innerArgs = new String[args.length-opti];
9931 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9932
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009933 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9934 long nativePss=0, dalvikPss=0, otherPss=0;
9935 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9936
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009937 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
9938 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
9939 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009940
9941 long totalPss = 0;
9942
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009943 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9944 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009945 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009946 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009947 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9948 pw.flush();
9949 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009950 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009951 if (dumpAll) {
9952 try {
9953 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9954 } catch (RemoteException e) {
9955 if (!isCheckinRequest) {
9956 pw.println("Got RemoteException!");
9957 pw.flush();
9958 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009959 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009960 } else {
9961 mi = new Debug.MemoryInfo();
9962 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009963 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009964
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009965 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009966 long myTotalPss = mi.getTotalPss();
9967 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009968 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009969 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009970 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009971
9972 nativePss += mi.nativePss;
9973 dalvikPss += mi.dalvikPss;
9974 otherPss += mi.otherPss;
9975 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9976 long mem = mi.getOtherPss(j);
9977 miscPss[j] += mem;
9978 otherPss -= mem;
9979 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009980
9981 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009982 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
9983 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009984 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009985 if (oomProcs[oomIndex] == null) {
9986 oomProcs[oomIndex] = new ArrayList<MemItem>();
9987 }
9988 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009989 break;
9990 }
9991 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009992 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009993 }
9994 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009995
9996 if (!isCheckinRequest && procs.size() > 1) {
9997 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9998
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009999 catMems.add(new MemItem("Native", "Native", nativePss, -1));
10000 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10001 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010002 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010003 String label = Debug.MemoryInfo.getOtherLabel(j);
10004 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010005 }
10006
Dianne Hackbornb437e092011-08-05 17:50:29 -070010007 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10008 for (int j=0; j<oomPss.length; j++) {
10009 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010010 String label = DUMP_MEM_OOM_LABEL[j];
10011 MemItem item = new MemItem(label, label, oomPss[j],
10012 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010013 item.subitems = oomProcs[j];
10014 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010015 }
10016 }
10017
Dianne Hackborn672342c2011-11-29 11:29:02 -080010018 if (outTag != null || outStack != null) {
10019 if (outTag != null) {
10020 appendMemBucket(outTag, totalPss, "total", false);
10021 }
10022 if (outStack != null) {
10023 appendMemBucket(outStack, totalPss, "total", true);
10024 }
10025 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010026 for (int i=0; i<oomMems.size(); i++) {
10027 MemItem miCat = oomMems.get(i);
10028 if (miCat.subitems == null || miCat.subitems.size() < 1) {
10029 continue;
10030 }
10031 if (miCat.id < ProcessList.SERVICE_ADJ
10032 || miCat.id == ProcessList.HOME_APP_ADJ
10033 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010034 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10035 outTag.append(" / ");
10036 }
10037 if (outStack != null) {
10038 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10039 if (firstLine) {
10040 outStack.append(":");
10041 firstLine = false;
10042 }
10043 outStack.append("\n\t at ");
10044 } else {
10045 outStack.append("$");
10046 }
10047 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010048 for (int j=0; j<miCat.subitems.size(); j++) {
10049 MemItem mi = miCat.subitems.get(j);
10050 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010051 if (outTag != null) {
10052 outTag.append(" ");
10053 }
10054 if (outStack != null) {
10055 outStack.append("$");
10056 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010057 }
Dianne Hackborn672342c2011-11-29 11:29:02 -080010058 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10059 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10060 }
10061 if (outStack != null) {
10062 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10063 }
10064 }
10065 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10066 outStack.append("(");
10067 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10068 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10069 outStack.append(DUMP_MEM_OOM_LABEL[k]);
10070 outStack.append(":");
10071 outStack.append(DUMP_MEM_OOM_ADJ[k]);
10072 }
10073 }
10074 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010075 }
10076 }
10077 }
10078 }
10079
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010080 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010081 pw.println();
10082 pw.println("Total PSS by process:");
10083 dumpMemItems(pw, " ", procMems, true);
10084 pw.println();
10085 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010086 pw.println("Total PSS by OOM adjustment:");
10087 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010088 if (!oomOnly) {
10089 PrintWriter out = categoryPw != null ? categoryPw : pw;
10090 out.println();
10091 out.println("Total PSS by category:");
10092 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010093 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010094 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010095 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010096 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010097 }
10098
10099 /**
10100 * Searches array of arguments for the specified string
10101 * @param args array of argument strings
10102 * @param value value to search for
10103 * @return true if the value is contained in the array
10104 */
10105 private static boolean scanArgs(String[] args, String value) {
10106 if (args != null) {
10107 for (String arg : args) {
10108 if (value.equals(arg)) {
10109 return true;
10110 }
10111 }
10112 }
10113 return false;
10114 }
10115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010116 private final void killServicesLocked(ProcessRecord app,
10117 boolean allowRestart) {
10118 // Report disconnected services.
10119 if (false) {
10120 // XXX we are letting the client link to the service for
10121 // death notifications.
10122 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010123 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010124 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010125 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010126 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010127 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010128 = r.connections.values().iterator();
10129 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010130 ArrayList<ConnectionRecord> cl = jt.next();
10131 for (int i=0; i<cl.size(); i++) {
10132 ConnectionRecord c = cl.get(i);
10133 if (c.binding.client != app) {
10134 try {
10135 //c.conn.connected(r.className, null);
10136 } catch (Exception e) {
10137 // todo: this should be asynchronous!
10138 Slog.w(TAG, "Exception thrown disconnected servce "
10139 + r.shortName
10140 + " from app " + app.processName, e);
10141 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010142 }
10143 }
10144 }
10145 }
10146 }
10147 }
10148 }
10149
10150 // Clean up any connections this application has to other services.
10151 if (app.connections.size() > 0) {
10152 Iterator<ConnectionRecord> it = app.connections.iterator();
10153 while (it.hasNext()) {
10154 ConnectionRecord r = it.next();
10155 removeConnectionLocked(r, app, null);
10156 }
10157 }
10158 app.connections.clear();
10159
10160 if (app.services.size() != 0) {
10161 // Any services running in the application need to be placed
10162 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -070010163 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010164 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010165 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010166 synchronized (sr.stats.getBatteryStats()) {
10167 sr.stats.stopLaunchedLocked();
10168 }
10169 sr.app = null;
10170 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010171 if (mStoppingServices.remove(sr)) {
10172 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10173 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010174
10175 boolean hasClients = sr.bindings.size() > 0;
10176 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010177 Iterator<IntentBindRecord> bindings
10178 = sr.bindings.values().iterator();
10179 while (bindings.hasNext()) {
10180 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010181 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010182 + ": shouldUnbind=" + b.hasBound);
10183 b.binder = null;
10184 b.requested = b.received = b.hasBound = false;
10185 }
10186 }
10187
Dianne Hackborn070783f2010-12-29 16:46:28 -080010188 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10189 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010190 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010191 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010192 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010193 sr.crashCount, sr.shortName, app.pid);
10194 bringDownServiceLocked(sr, true);
10195 } else if (!allowRestart) {
10196 bringDownServiceLocked(sr, true);
10197 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010198 boolean canceled = scheduleServiceRestartLocked(sr, true);
10199
10200 // Should the service remain running? Note that in the
10201 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010202 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010203 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10204 if (sr.pendingStarts.size() == 0) {
10205 sr.startRequested = false;
10206 if (!hasClients) {
10207 // Whoops, no reason to restart!
10208 bringDownServiceLocked(sr, true);
10209 }
10210 }
10211 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010212 }
10213 }
10214
10215 if (!allowRestart) {
10216 app.services.clear();
10217 }
10218 }
10219
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010220 // Make sure we have no more records on the stopping list.
10221 int i = mStoppingServices.size();
10222 while (i > 0) {
10223 i--;
10224 ServiceRecord sr = mStoppingServices.get(i);
10225 if (sr.app == app) {
10226 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010227 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010228 }
10229 }
10230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010231 app.executingServices.clear();
10232 }
10233
10234 private final void removeDyingProviderLocked(ProcessRecord proc,
10235 ContentProviderRecord cpr) {
10236 synchronized (cpr) {
10237 cpr.launchingApp = null;
10238 cpr.notifyAll();
10239 }
10240
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010241 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010242 String names[] = cpr.info.authority.split(";");
10243 for (int j = 0; j < names.length; j++) {
10244 mProvidersByName.remove(names[j]);
10245 }
10246
10247 Iterator<ProcessRecord> cit = cpr.clients.iterator();
10248 while (cit.hasNext()) {
10249 ProcessRecord capp = cit.next();
10250 if (!capp.persistent && capp.thread != null
10251 && capp.pid != 0
10252 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010253 Slog.i(TAG, "Kill " + capp.processName
10254 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010255 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -070010256 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010257 capp.processName, capp.setAdj, "dying provider "
10258 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010259 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010260 }
10261 }
10262
10263 mLaunchingProviders.remove(cpr);
10264 }
10265
10266 /**
10267 * Main code for cleaning up a process when it has gone away. This is
10268 * called both as a result of the process dying, or directly when stopping
10269 * a process when running in single process mode.
10270 */
10271 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010272 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010273 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010274 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010275 }
10276
Dianne Hackborn36124872009-10-08 16:22:03 -070010277 mProcessesToGc.remove(app);
10278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010279 // Dismiss any open dialogs.
10280 if (app.crashDialog != null) {
10281 app.crashDialog.dismiss();
10282 app.crashDialog = null;
10283 }
10284 if (app.anrDialog != null) {
10285 app.anrDialog.dismiss();
10286 app.anrDialog = null;
10287 }
10288 if (app.waitDialog != null) {
10289 app.waitDialog.dismiss();
10290 app.waitDialog = null;
10291 }
10292
10293 app.crashing = false;
10294 app.notResponding = false;
10295
10296 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070010297 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010298 app.thread = null;
10299 app.forcingToForeground = null;
10300 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010301 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070010302 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010303 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010304
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010305 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010306
10307 boolean restart = false;
10308
10309 int NL = mLaunchingProviders.size();
10310
10311 // Remove published content providers.
10312 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010313 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010314 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010315 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010316 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010317 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010318
10319 // See if someone is waiting for this provider... in which
10320 // case we don't remove it, but just let it restart.
10321 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010322 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010323 for (; i<NL; i++) {
10324 if (mLaunchingProviders.get(i) == cpr) {
10325 restart = true;
10326 break;
10327 }
10328 }
10329 } else {
10330 i = NL;
10331 }
10332
10333 if (i >= NL) {
10334 removeDyingProviderLocked(app, cpr);
10335 NL = mLaunchingProviders.size();
10336 }
10337 }
10338 app.pubProviders.clear();
10339 }
10340
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010341 // Take care of any launching providers waiting for this process.
10342 if (checkAppInLaunchingProvidersLocked(app, false)) {
10343 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010344 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010345
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010346 // Unregister from connected content providers.
10347 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -070010348 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010349 while (it.hasNext()) {
10350 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10351 cpr.clients.remove(app);
10352 }
10353 app.conProviders.clear();
10354 }
10355
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010356 // At this point there may be remaining entries in mLaunchingProviders
10357 // where we were the only one waiting, so they are no longer of use.
10358 // Look for these and clean up if found.
10359 // XXX Commented out for now. Trying to figure out a way to reproduce
10360 // the actual situation to identify what is actually going on.
10361 if (false) {
10362 for (int i=0; i<NL; i++) {
10363 ContentProviderRecord cpr = (ContentProviderRecord)
10364 mLaunchingProviders.get(i);
10365 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
10366 synchronized (cpr) {
10367 cpr.launchingApp = null;
10368 cpr.notifyAll();
10369 }
10370 }
10371 }
10372 }
10373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010374 skipCurrentReceiverLocked(app);
10375
10376 // Unregister any receivers.
10377 if (app.receivers.size() > 0) {
10378 Iterator<ReceiverList> it = app.receivers.iterator();
10379 while (it.hasNext()) {
10380 removeReceiverLocked(it.next());
10381 }
10382 app.receivers.clear();
10383 }
10384
Christopher Tate181fafa2009-05-14 11:12:14 -070010385 // If the app is undergoing backup, tell the backup manager about it
10386 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010387 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070010388 try {
10389 IBackupManager bm = IBackupManager.Stub.asInterface(
10390 ServiceManager.getService(Context.BACKUP_SERVICE));
10391 bm.agentDisconnected(app.info.packageName);
10392 } catch (RemoteException e) {
10393 // can't happen; backup manager is local
10394 }
10395 }
10396
Jeff Sharkey287bd832011-05-28 19:36:26 -070010397 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010399 // If the caller is restarting this app, then leave it in its
10400 // current lists and let the caller take care of it.
10401 if (restarting) {
10402 return;
10403 }
10404
10405 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010406 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010407 "Removing non-persistent process during cleanup: " + app);
10408 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070010409 if (mHeavyWeightProcess == app) {
10410 mHeavyWeightProcess = null;
10411 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010413 } else if (!app.removed) {
10414 // This app is persistent, so we need to keep its record around.
10415 // If it is not already on the pending app list, add it there
10416 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010417 if (mPersistentStartingProcesses.indexOf(app) < 0) {
10418 mPersistentStartingProcesses.add(app);
10419 restart = true;
10420 }
10421 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010422 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10423 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010424 mProcessesOnHold.remove(app);
10425
The Android Open Source Project4df24232009-03-05 14:34:35 -080010426 if (app == mHomeProcess) {
10427 mHomeProcess = null;
10428 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010429 if (app == mPreviousProcess) {
10430 mPreviousProcess = null;
10431 }
10432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010433 if (restart) {
10434 // We have components that still need to be running in the
10435 // process, so re-launch it.
10436 mProcessNames.put(app.processName, app.info.uid, app);
10437 startProcessLocked(app, "restart", app.processName);
10438 } else if (app.pid > 0 && app.pid != MY_PID) {
10439 // Goodbye!
10440 synchronized (mPidsSelfLocked) {
10441 mPidsSelfLocked.remove(app.pid);
10442 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10443 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010444 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010445 }
10446 }
10447
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010448 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10449 // Look through the content providers we are waiting to have launched,
10450 // and if any run in this process then either schedule a restart of
10451 // the process or kill the client waiting for it if this process has
10452 // gone bad.
10453 int NL = mLaunchingProviders.size();
10454 boolean restart = false;
10455 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010456 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010457 if (cpr.launchingApp == app) {
10458 if (!alwaysBad && !app.bad) {
10459 restart = true;
10460 } else {
10461 removeDyingProviderLocked(app, cpr);
10462 NL = mLaunchingProviders.size();
10463 }
10464 }
10465 }
10466 return restart;
10467 }
10468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010469 // =========================================================
10470 // SERVICES
10471 // =========================================================
10472
10473 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10474 ActivityManager.RunningServiceInfo info =
10475 new ActivityManager.RunningServiceInfo();
10476 info.service = r.name;
10477 if (r.app != null) {
10478 info.pid = r.app.pid;
10479 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010480 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010481 info.process = r.processName;
10482 info.foreground = r.isForeground;
10483 info.activeSince = r.createTime;
10484 info.started = r.startRequested;
10485 info.clientCount = r.connections.size();
10486 info.crashCount = r.crashCount;
10487 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010488 if (r.isForeground) {
10489 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10490 }
10491 if (r.startRequested) {
10492 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10493 }
Dan Egnor42471dd2010-01-07 17:25:22 -080010494 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010495 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10496 }
10497 if (r.app != null && r.app.persistent) {
10498 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10499 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010500
10501 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10502 for (int i=0; i<connl.size(); i++) {
10503 ConnectionRecord conn = connl.get(i);
10504 if (conn.clientLabel != 0) {
10505 info.clientPackage = conn.binding.client.info.packageName;
10506 info.clientLabel = conn.clientLabel;
10507 return info;
10508 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010509 }
10510 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010511 return info;
10512 }
10513
10514 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10515 int flags) {
10516 synchronized (this) {
10517 ArrayList<ActivityManager.RunningServiceInfo> res
10518 = new ArrayList<ActivityManager.RunningServiceInfo>();
10519
10520 if (mServices.size() > 0) {
10521 Iterator<ServiceRecord> it = mServices.values().iterator();
10522 while (it.hasNext() && res.size() < maxNum) {
10523 res.add(makeRunningServiceInfoLocked(it.next()));
10524 }
10525 }
10526
10527 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10528 ServiceRecord r = mRestartingServices.get(i);
10529 ActivityManager.RunningServiceInfo info =
10530 makeRunningServiceInfoLocked(r);
10531 info.restarting = r.nextRestartTime;
10532 res.add(info);
10533 }
10534
10535 return res;
10536 }
10537 }
10538
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010539 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10540 synchronized (this) {
10541 ServiceRecord r = mServices.get(name);
10542 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010543 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
10544 for (int i=0; i<conn.size(); i++) {
10545 if (conn.get(i).clientIntent != null) {
10546 return conn.get(i).clientIntent;
10547 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010548 }
10549 }
10550 }
10551 }
10552 return null;
10553 }
10554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010555 private final ServiceRecord findServiceLocked(ComponentName name,
10556 IBinder token) {
10557 ServiceRecord r = mServices.get(name);
10558 return r == token ? r : null;
10559 }
10560
10561 private final class ServiceLookupResult {
10562 final ServiceRecord record;
10563 final String permission;
10564
10565 ServiceLookupResult(ServiceRecord _record, String _permission) {
10566 record = _record;
10567 permission = _permission;
10568 }
10569 };
10570
10571 private ServiceLookupResult findServiceLocked(Intent service,
10572 String resolvedType) {
10573 ServiceRecord r = null;
10574 if (service.getComponent() != null) {
10575 r = mServices.get(service.getComponent());
10576 }
10577 if (r == null) {
10578 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10579 r = mServicesByIntent.get(filter);
10580 }
10581
10582 if (r == null) {
10583 try {
10584 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010585 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010586 service, resolvedType, 0);
10587 ServiceInfo sInfo =
10588 rInfo != null ? rInfo.serviceInfo : null;
10589 if (sInfo == null) {
10590 return null;
10591 }
10592
10593 ComponentName name = new ComponentName(
10594 sInfo.applicationInfo.packageName, sInfo.name);
10595 r = mServices.get(name);
10596 } catch (RemoteException ex) {
10597 // pm is in same process, this will never happen.
10598 }
10599 }
10600 if (r != null) {
10601 int callingPid = Binder.getCallingPid();
10602 int callingUid = Binder.getCallingUid();
10603 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010604 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010605 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010606 if (!r.exported) {
10607 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10608 + " from pid=" + callingPid
10609 + ", uid=" + callingUid
10610 + " that is not exported from uid " + r.appInfo.uid);
10611 return new ServiceLookupResult(null, "not exported from uid "
10612 + r.appInfo.uid);
10613 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010614 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010615 + " from pid=" + callingPid
10616 + ", uid=" + callingUid
10617 + " requires " + r.permission);
10618 return new ServiceLookupResult(null, r.permission);
10619 }
10620 return new ServiceLookupResult(r, null);
10621 }
10622 return null;
10623 }
10624
10625 private class ServiceRestarter implements Runnable {
10626 private ServiceRecord mService;
10627
10628 void setService(ServiceRecord service) {
10629 mService = service;
10630 }
10631
10632 public void run() {
10633 synchronized(ActivityManagerService.this) {
10634 performServiceRestartLocked(mService);
10635 }
10636 }
10637 }
10638
10639 private ServiceLookupResult retrieveServiceLocked(Intent service,
10640 String resolvedType, int callingPid, int callingUid) {
10641 ServiceRecord r = null;
10642 if (service.getComponent() != null) {
10643 r = mServices.get(service.getComponent());
10644 }
10645 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10646 r = mServicesByIntent.get(filter);
10647 if (r == null) {
10648 try {
10649 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010650 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010651 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010652 ServiceInfo sInfo =
10653 rInfo != null ? rInfo.serviceInfo : null;
10654 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010655 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010656 ": not found");
10657 return null;
10658 }
10659
10660 ComponentName name = new ComponentName(
10661 sInfo.applicationInfo.packageName, sInfo.name);
10662 r = mServices.get(name);
10663 if (r == null) {
10664 filter = new Intent.FilterComparison(service.cloneFilter());
10665 ServiceRestarter res = new ServiceRestarter();
10666 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10667 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10668 synchronized (stats) {
10669 ss = stats.getServiceStatsLocked(
10670 sInfo.applicationInfo.uid, sInfo.packageName,
10671 sInfo.name);
10672 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080010673 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010674 res.setService(r);
10675 mServices.put(name, r);
10676 mServicesByIntent.put(filter, r);
10677
10678 // Make sure this component isn't in the pending list.
10679 int N = mPendingServices.size();
10680 for (int i=0; i<N; i++) {
10681 ServiceRecord pr = mPendingServices.get(i);
10682 if (pr.name.equals(name)) {
10683 mPendingServices.remove(i);
10684 i--;
10685 N--;
10686 }
10687 }
10688 }
10689 } catch (RemoteException ex) {
10690 // pm is in same process, this will never happen.
10691 }
10692 }
10693 if (r != null) {
10694 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010695 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010696 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010697 if (!r.exported) {
10698 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10699 + " from pid=" + callingPid
10700 + ", uid=" + callingUid
10701 + " that is not exported from uid " + r.appInfo.uid);
10702 return new ServiceLookupResult(null, "not exported from uid "
10703 + r.appInfo.uid);
10704 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010705 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010706 + " from pid=" + callingPid
10707 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010708 + " requires " + r.permission);
10709 return new ServiceLookupResult(null, r.permission);
10710 }
10711 return new ServiceLookupResult(r, null);
10712 }
10713 return null;
10714 }
10715
Dianne Hackborn287952c2010-09-22 22:34:31 -070010716 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
10717 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
10718 + why + " of " + r + " in app " + r.app);
10719 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
10720 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010721 long now = SystemClock.uptimeMillis();
10722 if (r.executeNesting == 0 && r.app != null) {
10723 if (r.app.executingServices.size() == 0) {
10724 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10725 msg.obj = r.app;
10726 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10727 }
10728 r.app.executingServices.add(r);
10729 }
10730 r.executeNesting++;
10731 r.executingStart = now;
10732 }
10733
10734 private final void sendServiceArgsLocked(ServiceRecord r,
10735 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010736 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010737 if (N == 0) {
10738 return;
10739 }
10740
Dianne Hackborn39792d22010-08-19 18:01:52 -070010741 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010742 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010743 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010744 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10745 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010746 if (si.intent == null && N > 1) {
10747 // If somehow we got a dummy null intent in the middle,
10748 // then skip it. DO NOT skip a null intent when it is
10749 // the only one in the list -- this is to support the
10750 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010751 continue;
10752 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010753 si.deliveredTime = SystemClock.uptimeMillis();
10754 r.deliveredStarts.add(si);
10755 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010756 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010757 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010758 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010759 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010760 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010761 if (!oomAdjusted) {
10762 oomAdjusted = true;
10763 updateOomAdjLocked(r.app);
10764 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010765 int flags = 0;
10766 if (si.deliveryCount > 0) {
10767 flags |= Service.START_FLAG_RETRY;
10768 }
10769 if (si.doneExecutingCount > 0) {
10770 flags |= Service.START_FLAG_REDELIVERY;
10771 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010772 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010773 } catch (RemoteException e) {
10774 // Remote process gone... we'll let the normal cleanup take
10775 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010776 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010777 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010778 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010779 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010780 break;
10781 }
10782 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010783 }
10784
10785 private final boolean requestServiceBindingLocked(ServiceRecord r,
10786 IntentBindRecord i, boolean rebind) {
10787 if (r.app == null || r.app.thread == null) {
10788 // If service is not currently running, can't yet bind.
10789 return false;
10790 }
10791 if ((!i.requested || rebind) && i.apps.size() > 0) {
10792 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010793 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010794 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10795 if (!rebind) {
10796 i.requested = true;
10797 }
10798 i.hasBound = true;
10799 i.doRebind = false;
10800 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010801 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010802 return false;
10803 }
10804 }
10805 return true;
10806 }
10807
10808 private final void requestServiceBindingsLocked(ServiceRecord r) {
10809 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10810 while (bindings.hasNext()) {
10811 IntentBindRecord i = bindings.next();
10812 if (!requestServiceBindingLocked(r, i, false)) {
10813 break;
10814 }
10815 }
10816 }
10817
10818 private final void realStartServiceLocked(ServiceRecord r,
10819 ProcessRecord app) throws RemoteException {
10820 if (app.thread == null) {
10821 throw new RemoteException();
10822 }
10823
10824 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010825 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010826
10827 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010828 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010829 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010830
10831 boolean created = false;
10832 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010833 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010834 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010835 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010836 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010837 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010838 synchronized (r.stats.getBatteryStats()) {
10839 r.stats.startLaunchedLocked();
10840 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010841 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010842 app.thread.scheduleCreateService(r, r.serviceInfo,
10843 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010844 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010845 created = true;
10846 } finally {
10847 if (!created) {
10848 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010849 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010850 }
10851 }
10852
10853 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010854
10855 // If the service is in the started state, and there are no
10856 // pending arguments, then fake up one so its onStartCommand() will
10857 // be called.
10858 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010859 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10860 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010861 }
10862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010863 sendServiceArgsLocked(r, true);
10864 }
10865
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010866 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10867 boolean allowCancel) {
10868 boolean canceled = false;
10869
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010870 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010871 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010872 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010873
Dianne Hackborn070783f2010-12-29 16:46:28 -080010874 if ((r.serviceInfo.applicationInfo.flags
10875 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10876 minDuration /= 4;
10877 }
10878
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010879 // Any delivered but not yet finished starts should be put back
10880 // on the pending list.
10881 final int N = r.deliveredStarts.size();
10882 if (N > 0) {
10883 for (int i=N-1; i>=0; i--) {
10884 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010885 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010886 if (si.intent == null) {
10887 // We'll generate this again if needed.
10888 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10889 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10890 r.pendingStarts.add(0, si);
10891 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10892 dur *= 2;
10893 if (minDuration < dur) minDuration = dur;
10894 if (resetTime < dur) resetTime = dur;
10895 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010896 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010897 + r.name);
10898 canceled = true;
10899 }
10900 }
10901 r.deliveredStarts.clear();
10902 }
10903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010904 r.totalRestartCount++;
10905 if (r.restartDelay == 0) {
10906 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010907 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010908 } else {
10909 // If it has been a "reasonably long time" since the service
10910 // was started, then reset our restart duration back to
10911 // the beginning, so we don't infinitely increase the duration
10912 // on a service that just occasionally gets killed (which is
10913 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010914 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010915 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010916 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010917 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010918 if ((r.serviceInfo.applicationInfo.flags
10919 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10920 // Services in peristent processes will restart much more
10921 // quickly, since they are pretty important. (Think SystemUI).
10922 r.restartDelay += minDuration/2;
10923 } else {
10924 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10925 if (r.restartDelay < minDuration) {
10926 r.restartDelay = minDuration;
10927 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010928 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010929 }
10930 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010931
10932 r.nextRestartTime = now + r.restartDelay;
10933
10934 // Make sure that we don't end up restarting a bunch of services
10935 // all at the same time.
10936 boolean repeat;
10937 do {
10938 repeat = false;
10939 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10940 ServiceRecord r2 = mRestartingServices.get(i);
10941 if (r2 != r && r.nextRestartTime
10942 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10943 && r.nextRestartTime
10944 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10945 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10946 r.restartDelay = r.nextRestartTime - now;
10947 repeat = true;
10948 break;
10949 }
10950 }
10951 } while (repeat);
10952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010953 if (!mRestartingServices.contains(r)) {
10954 mRestartingServices.add(r);
10955 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010956
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010957 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010959 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010960 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010961 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010962 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010963 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010964 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010965 r.shortName, r.restartDelay);
10966
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010967 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010968 }
10969
10970 final void performServiceRestartLocked(ServiceRecord r) {
10971 if (!mRestartingServices.contains(r)) {
10972 return;
10973 }
10974 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10975 }
10976
10977 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10978 if (r.restartDelay == 0) {
10979 return false;
10980 }
10981 r.resetRestartCounter();
10982 mRestartingServices.remove(r);
10983 mHandler.removeCallbacks(r.restarter);
10984 return true;
10985 }
10986
10987 private final boolean bringUpServiceLocked(ServiceRecord r,
10988 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010989 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010990 //r.dump(" ");
10991
Dianne Hackborn36124872009-10-08 16:22:03 -070010992 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010993 sendServiceArgsLocked(r, false);
10994 return true;
10995 }
10996
10997 if (!whileRestarting && r.restartDelay > 0) {
10998 // If waiting for a restart, then do nothing.
10999 return true;
11000 }
11001
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011002 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011003
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011004 // We are now bringing the service up, so no longer in the
11005 // restarting state.
11006 mRestartingServices.remove(r);
11007
Dianne Hackborne7f97212011-02-24 14:40:20 -080011008 // Service is now being launched, its package can't be stopped.
11009 try {
11010 AppGlobals.getPackageManager().setPackageStoppedState(
11011 r.packageName, false);
11012 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011013 } catch (IllegalArgumentException e) {
11014 Slog.w(TAG, "Failed trying to unstop package "
11015 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011016 }
11017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011018 final String appName = r.processName;
11019 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
11020 if (app != null && app.thread != null) {
11021 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011022 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011023 realStartServiceLocked(r, app);
11024 return true;
11025 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011026 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011027 }
11028
11029 // If a dead object exception was thrown -- fall through to
11030 // restart the application.
11031 }
11032
Dianne Hackborn36124872009-10-08 16:22:03 -070011033 // Not running -- get it started, and enqueue this service record
11034 // to be executed when the app comes up.
11035 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
11036 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011037 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070011038 + r.appInfo.packageName + "/"
11039 + r.appInfo.uid + " for service "
11040 + r.intent.getIntent() + ": process is bad");
11041 bringDownServiceLocked(r, true);
11042 return false;
11043 }
11044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011045 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011046 mPendingServices.add(r);
11047 }
Dianne Hackborn36124872009-10-08 16:22:03 -070011048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011049 return true;
11050 }
11051
11052 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011053 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011054 //r.dump(" ");
11055
11056 // Does it still need to run?
11057 if (!force && r.startRequested) {
11058 return;
11059 }
11060 if (r.connections.size() > 0) {
11061 if (!force) {
11062 // XXX should probably keep a count of the number of auto-create
11063 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011064 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011065 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011066 ArrayList<ConnectionRecord> cr = it.next();
11067 for (int i=0; i<cr.size(); i++) {
11068 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
11069 return;
11070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011071 }
11072 }
11073 }
11074
11075 // Report to all of the connections that the service is no longer
11076 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011077 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011078 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011079 ArrayList<ConnectionRecord> c = it.next();
11080 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011081 ConnectionRecord cr = c.get(i);
11082 // There is still a connection to the service that is
11083 // being brought down. Mark it as dead.
11084 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011085 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011086 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011087 } catch (Exception e) {
11088 Slog.w(TAG, "Failure disconnecting service " + r.name +
11089 " to connection " + c.get(i).conn.asBinder() +
11090 " (in " + c.get(i).binding.client.processName + ")", e);
11091 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011092 }
11093 }
11094 }
11095
11096 // Tell the service that it has been unbound.
11097 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
11098 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
11099 while (it.hasNext()) {
11100 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011101 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011102 + ": hasBound=" + ibr.hasBound);
11103 if (r.app != null && r.app.thread != null && ibr.hasBound) {
11104 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011105 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011106 updateOomAdjLocked(r.app);
11107 ibr.hasBound = false;
11108 r.app.thread.scheduleUnbindService(r,
11109 ibr.intent.getIntent());
11110 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011111 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011112 + r.shortName, e);
11113 serviceDoneExecutingLocked(r, true);
11114 }
11115 }
11116 }
11117 }
11118
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011119 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011120 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011121 System.identityHashCode(r), r.shortName,
11122 (r.app != null) ? r.app.pid : -1);
11123
11124 mServices.remove(r.name);
11125 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011126 r.totalRestartCount = 0;
11127 unscheduleServiceRestartLocked(r);
11128
11129 // Also make sure it is not on the pending list.
11130 int N = mPendingServices.size();
11131 for (int i=0; i<N; i++) {
11132 if (mPendingServices.get(i) == r) {
11133 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011134 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011135 i--;
11136 N--;
11137 }
11138 }
11139
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011140 r.cancelNotification();
11141 r.isForeground = false;
11142 r.foregroundId = 0;
11143 r.foregroundNoti = null;
11144
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011145 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070011146 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011147 r.pendingStarts.clear();
11148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011149 if (r.app != null) {
11150 synchronized (r.stats.getBatteryStats()) {
11151 r.stats.stopLaunchedLocked();
11152 }
11153 r.app.services.remove(r);
11154 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011155 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011156 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011157 mStoppingServices.add(r);
11158 updateOomAdjLocked(r.app);
11159 r.app.thread.scheduleStopService(r);
11160 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011161 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011162 + r.shortName, e);
11163 serviceDoneExecutingLocked(r, true);
11164 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011165 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011166 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011167 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011168 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011169 }
11170 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011171 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011172 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011173 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080011174
11175 if (r.bindings.size() > 0) {
11176 r.bindings.clear();
11177 }
11178
11179 if (r.restarter instanceof ServiceRestarter) {
11180 ((ServiceRestarter)r.restarter).setService(null);
11181 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011182 }
11183
11184 ComponentName startServiceLocked(IApplicationThread caller,
11185 Intent service, String resolvedType,
11186 int callingPid, int callingUid) {
11187 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011188 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011189 + " type=" + resolvedType + " args=" + service.getExtras());
11190
11191 if (caller != null) {
11192 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11193 if (callerApp == null) {
11194 throw new SecurityException(
11195 "Unable to find app for caller " + caller
11196 + " (pid=" + Binder.getCallingPid()
11197 + ") when starting service " + service);
11198 }
11199 }
11200
11201 ServiceLookupResult res =
11202 retrieveServiceLocked(service, resolvedType,
11203 callingPid, callingUid);
11204 if (res == null) {
11205 return null;
11206 }
11207 if (res.record == null) {
11208 return new ComponentName("!", res.permission != null
11209 ? res.permission : "private to package");
11210 }
11211 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070011212 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
11213 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011214 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011215 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011216 }
11217 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011218 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011219 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070011220 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011221 r.lastActivity = SystemClock.uptimeMillis();
11222 synchronized (r.stats.getBatteryStats()) {
11223 r.stats.startRunningLocked();
11224 }
11225 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11226 return new ComponentName("!", "Service process is bad");
11227 }
11228 return r.name;
11229 }
11230 }
11231
11232 public ComponentName startService(IApplicationThread caller, Intent service,
11233 String resolvedType) {
11234 // Refuse possible leaked file descriptors
11235 if (service != null && service.hasFileDescriptors() == true) {
11236 throw new IllegalArgumentException("File descriptors passed in Intent");
11237 }
11238
11239 synchronized(this) {
11240 final int callingPid = Binder.getCallingPid();
11241 final int callingUid = Binder.getCallingUid();
11242 final long origId = Binder.clearCallingIdentity();
11243 ComponentName res = startServiceLocked(caller, service,
11244 resolvedType, callingPid, callingUid);
11245 Binder.restoreCallingIdentity(origId);
11246 return res;
11247 }
11248 }
11249
11250 ComponentName startServiceInPackage(int uid,
11251 Intent service, String resolvedType) {
11252 synchronized(this) {
11253 final long origId = Binder.clearCallingIdentity();
11254 ComponentName res = startServiceLocked(null, service,
11255 resolvedType, -1, uid);
11256 Binder.restoreCallingIdentity(origId);
11257 return res;
11258 }
11259 }
11260
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011261 private void stopServiceLocked(ServiceRecord service) {
11262 synchronized (service.stats.getBatteryStats()) {
11263 service.stats.stopRunningLocked();
11264 }
11265 service.startRequested = false;
11266 service.callStart = false;
11267 bringDownServiceLocked(service, false);
11268 }
11269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011270 public int stopService(IApplicationThread caller, Intent service,
11271 String resolvedType) {
11272 // Refuse possible leaked file descriptors
11273 if (service != null && service.hasFileDescriptors() == true) {
11274 throw new IllegalArgumentException("File descriptors passed in Intent");
11275 }
11276
11277 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011278 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011279 + " type=" + resolvedType);
11280
11281 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11282 if (caller != null && callerApp == null) {
11283 throw new SecurityException(
11284 "Unable to find app for caller " + caller
11285 + " (pid=" + Binder.getCallingPid()
11286 + ") when stopping service " + service);
11287 }
11288
11289 // If this service is active, make sure it is stopped.
11290 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11291 if (r != null) {
11292 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011293 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011294 try {
11295 stopServiceLocked(r.record);
11296 } finally {
11297 Binder.restoreCallingIdentity(origId);
11298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011299 return 1;
11300 }
11301 return -1;
11302 }
11303 }
11304
11305 return 0;
11306 }
11307
11308 public IBinder peekService(Intent service, String resolvedType) {
11309 // Refuse possible leaked file descriptors
11310 if (service != null && service.hasFileDescriptors() == true) {
11311 throw new IllegalArgumentException("File descriptors passed in Intent");
11312 }
11313
11314 IBinder ret = null;
11315
11316 synchronized(this) {
11317 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11318
11319 if (r != null) {
11320 // r.record is null if findServiceLocked() failed the caller permission check
11321 if (r.record == null) {
11322 throw new SecurityException(
11323 "Permission Denial: Accessing service " + r.record.name
11324 + " from pid=" + Binder.getCallingPid()
11325 + ", uid=" + Binder.getCallingUid()
11326 + " requires " + r.permission);
11327 }
11328 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11329 if (ib != null) {
11330 ret = ib.binder;
11331 }
11332 }
11333 }
11334
11335 return ret;
11336 }
11337
11338 public boolean stopServiceToken(ComponentName className, IBinder token,
11339 int startId) {
11340 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011341 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011342 + " " + token + " startId=" + startId);
11343 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011344 if (r != null) {
11345 if (startId >= 0) {
11346 // Asked to only stop if done with all work. Note that
11347 // to avoid leaks, we will take this as dropping all
11348 // start items up to and including this one.
11349 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11350 if (si != null) {
11351 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011352 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11353 cur.removeUriPermissionsLocked();
11354 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011355 break;
11356 }
11357 }
11358 }
11359
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011360 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011361 return false;
11362 }
11363
11364 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011365 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011366 + " is last, but have " + r.deliveredStarts.size()
11367 + " remaining args");
11368 }
11369 }
11370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011371 synchronized (r.stats.getBatteryStats()) {
11372 r.stats.stopRunningLocked();
11373 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011374 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011375 }
11376 final long origId = Binder.clearCallingIdentity();
11377 bringDownServiceLocked(r, false);
11378 Binder.restoreCallingIdentity(origId);
11379 return true;
11380 }
11381 }
11382 return false;
11383 }
11384
11385 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011386 int id, Notification notification, boolean removeNotification) {
11387 final long origId = Binder.clearCallingIdentity();
11388 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011389 synchronized(this) {
11390 ServiceRecord r = findServiceLocked(className, token);
11391 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011392 if (id != 0) {
11393 if (notification == null) {
11394 throw new IllegalArgumentException("null notification");
11395 }
11396 if (r.foregroundId != id) {
11397 r.cancelNotification();
11398 r.foregroundId = id;
11399 }
11400 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11401 r.foregroundNoti = notification;
11402 r.isForeground = true;
11403 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011404 if (r.app != null) {
11405 updateServiceForegroundLocked(r.app, true);
11406 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011407 } else {
11408 if (r.isForeground) {
11409 r.isForeground = false;
11410 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070011411 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011412 updateServiceForegroundLocked(r.app, true);
11413 }
11414 }
11415 if (removeNotification) {
11416 r.cancelNotification();
11417 r.foregroundId = 0;
11418 r.foregroundNoti = null;
11419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011420 }
11421 }
11422 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011423 } finally {
11424 Binder.restoreCallingIdentity(origId);
11425 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011426 }
11427
11428 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11429 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070011430 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011431 if (sr.isForeground) {
11432 anyForeground = true;
11433 break;
11434 }
11435 }
11436 if (anyForeground != proc.foregroundServices) {
11437 proc.foregroundServices = anyForeground;
11438 if (oomAdj) {
11439 updateOomAdjLocked();
11440 }
11441 }
11442 }
11443
11444 public int bindService(IApplicationThread caller, IBinder token,
11445 Intent service, String resolvedType,
11446 IServiceConnection connection, int flags) {
11447 // Refuse possible leaked file descriptors
11448 if (service != null && service.hasFileDescriptors() == true) {
11449 throw new IllegalArgumentException("File descriptors passed in Intent");
11450 }
11451
11452 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011453 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011454 + " type=" + resolvedType + " conn=" + connection.asBinder()
11455 + " flags=0x" + Integer.toHexString(flags));
11456 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11457 if (callerApp == null) {
11458 throw new SecurityException(
11459 "Unable to find app for caller " + caller
11460 + " (pid=" + Binder.getCallingPid()
11461 + ") when binding service " + service);
11462 }
11463
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011464 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011465 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011466 activity = mMainStack.isInStackLocked(token);
11467 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011468 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011469 return 0;
11470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011471 }
11472
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011473 int clientLabel = 0;
11474 PendingIntent clientIntent = null;
11475
11476 if (callerApp.info.uid == Process.SYSTEM_UID) {
11477 // Hacky kind of thing -- allow system stuff to tell us
11478 // what they are, so we can report this elsewhere for
11479 // others to know why certain services are running.
11480 try {
11481 clientIntent = (PendingIntent)service.getParcelableExtra(
11482 Intent.EXTRA_CLIENT_INTENT);
11483 } catch (RuntimeException e) {
11484 }
11485 if (clientIntent != null) {
11486 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11487 if (clientLabel != 0) {
11488 // There are no useful extras in the intent, trash them.
11489 // System code calling with this stuff just needs to know
11490 // this will happen.
11491 service = service.cloneFilter();
11492 }
11493 }
11494 }
11495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011496 ServiceLookupResult res =
11497 retrieveServiceLocked(service, resolvedType,
11498 Binder.getCallingPid(), Binder.getCallingUid());
11499 if (res == null) {
11500 return 0;
11501 }
11502 if (res.record == null) {
11503 return -1;
11504 }
11505 ServiceRecord s = res.record;
11506
11507 final long origId = Binder.clearCallingIdentity();
11508
11509 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011510 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011511 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011512 }
11513
11514 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11515 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011516 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011517
11518 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011519 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11520 if (clist == null) {
11521 clist = new ArrayList<ConnectionRecord>();
11522 s.connections.put(binder, clist);
11523 }
11524 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011525 b.connections.add(c);
11526 if (activity != null) {
11527 if (activity.connections == null) {
11528 activity.connections = new HashSet<ConnectionRecord>();
11529 }
11530 activity.connections.add(c);
11531 }
11532 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011533 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11534 b.client.hasAboveClient = true;
11535 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011536 clist = mServiceConnections.get(binder);
11537 if (clist == null) {
11538 clist = new ArrayList<ConnectionRecord>();
11539 mServiceConnections.put(binder, clist);
11540 }
11541 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011542
11543 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11544 s.lastActivity = SystemClock.uptimeMillis();
11545 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11546 return 0;
11547 }
11548 }
11549
11550 if (s.app != null) {
11551 // This could have made the service more important.
11552 updateOomAdjLocked(s.app);
11553 }
11554
Joe Onorato8a9b2202010-02-26 18:56:32 -080011555 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011556 + ": received=" + b.intent.received
11557 + " apps=" + b.intent.apps.size()
11558 + " doRebind=" + b.intent.doRebind);
11559
11560 if (s.app != null && b.intent.received) {
11561 // Service is already running, so we can immediately
11562 // publish the connection.
11563 try {
11564 c.conn.connected(s.name, b.intent.binder);
11565 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011566 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011567 + " to connection " + c.conn.asBinder()
11568 + " (in " + c.binding.client.processName + ")", e);
11569 }
11570
11571 // If this is the first app connected back to this binding,
11572 // and the service had previously asked to be told when
11573 // rebound, then do so.
11574 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11575 requestServiceBindingLocked(s, b.intent, true);
11576 }
11577 } else if (!b.intent.requested) {
11578 requestServiceBindingLocked(s, b.intent, false);
11579 }
11580
11581 Binder.restoreCallingIdentity(origId);
11582 }
11583
11584 return 1;
11585 }
11586
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011587 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011588 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011589 IBinder binder = c.conn.asBinder();
11590 AppBindRecord b = c.binding;
11591 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011592 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11593 if (clist != null) {
11594 clist.remove(c);
11595 if (clist.size() == 0) {
11596 s.connections.remove(binder);
11597 }
11598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011599 b.connections.remove(c);
11600 if (c.activity != null && c.activity != skipAct) {
11601 if (c.activity.connections != null) {
11602 c.activity.connections.remove(c);
11603 }
11604 }
11605 if (b.client != skipApp) {
11606 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011607 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11608 b.client.updateHasAboveClientLocked();
11609 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011610 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011611 clist = mServiceConnections.get(binder);
11612 if (clist != null) {
11613 clist.remove(c);
11614 if (clist.size() == 0) {
11615 mServiceConnections.remove(binder);
11616 }
11617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011618
11619 if (b.connections.size() == 0) {
11620 b.intent.apps.remove(b.client);
11621 }
11622
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011623 if (!c.serviceDead) {
11624 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
11625 + ": shouldUnbind=" + b.intent.hasBound);
11626 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11627 && b.intent.hasBound) {
11628 try {
11629 bumpServiceExecutingLocked(s, "unbind");
11630 updateOomAdjLocked(s.app);
11631 b.intent.hasBound = false;
11632 // Assume the client doesn't want to know about a rebind;
11633 // we will deal with that later if it asks for one.
11634 b.intent.doRebind = false;
11635 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11636 } catch (Exception e) {
11637 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
11638 serviceDoneExecutingLocked(s, true);
11639 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011640 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011641
11642 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11643 bringDownServiceLocked(s, false);
11644 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011645 }
11646 }
11647
11648 public boolean unbindService(IServiceConnection connection) {
11649 synchronized (this) {
11650 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011651 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011652 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
11653 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011654 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011655 + connection.asBinder());
11656 return false;
11657 }
11658
11659 final long origId = Binder.clearCallingIdentity();
11660
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011661 while (clist.size() > 0) {
11662 ConnectionRecord r = clist.get(0);
11663 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011664
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011665 if (r.binding.service.app != null) {
11666 // This could have made the service less important.
11667 updateOomAdjLocked(r.binding.service.app);
11668 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011669 }
11670
11671 Binder.restoreCallingIdentity(origId);
11672 }
11673
11674 return true;
11675 }
11676
11677 public void publishService(IBinder token, Intent intent, IBinder service) {
11678 // Refuse possible leaked file descriptors
11679 if (intent != null && intent.hasFileDescriptors() == true) {
11680 throw new IllegalArgumentException("File descriptors passed in Intent");
11681 }
11682
11683 synchronized(this) {
11684 if (!(token instanceof ServiceRecord)) {
11685 throw new IllegalArgumentException("Invalid service token");
11686 }
11687 ServiceRecord r = (ServiceRecord)token;
11688
11689 final long origId = Binder.clearCallingIdentity();
11690
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011691 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011692 + " " + intent + ": " + service);
11693 if (r != null) {
11694 Intent.FilterComparison filter
11695 = new Intent.FilterComparison(intent);
11696 IntentBindRecord b = r.bindings.get(filter);
11697 if (b != null && !b.received) {
11698 b.binder = service;
11699 b.requested = true;
11700 b.received = true;
11701 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011702 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011703 = r.connections.values().iterator();
11704 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011705 ArrayList<ConnectionRecord> clist = it.next();
11706 for (int i=0; i<clist.size(); i++) {
11707 ConnectionRecord c = clist.get(i);
11708 if (!filter.equals(c.binding.intent.intent)) {
11709 if (DEBUG_SERVICE) Slog.v(
11710 TAG, "Not publishing to: " + c);
11711 if (DEBUG_SERVICE) Slog.v(
11712 TAG, "Bound intent: " + c.binding.intent.intent);
11713 if (DEBUG_SERVICE) Slog.v(
11714 TAG, "Published intent: " + intent);
11715 continue;
11716 }
11717 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
11718 try {
11719 c.conn.connected(r.name, service);
11720 } catch (Exception e) {
11721 Slog.w(TAG, "Failure sending service " + r.name +
11722 " to connection " + c.conn.asBinder() +
11723 " (in " + c.binding.client.processName + ")", e);
11724 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011725 }
11726 }
11727 }
11728 }
11729
11730 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11731
11732 Binder.restoreCallingIdentity(origId);
11733 }
11734 }
11735 }
11736
11737 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11738 // Refuse possible leaked file descriptors
11739 if (intent != null && intent.hasFileDescriptors() == true) {
11740 throw new IllegalArgumentException("File descriptors passed in Intent");
11741 }
11742
11743 synchronized(this) {
11744 if (!(token instanceof ServiceRecord)) {
11745 throw new IllegalArgumentException("Invalid service token");
11746 }
11747 ServiceRecord r = (ServiceRecord)token;
11748
11749 final long origId = Binder.clearCallingIdentity();
11750
11751 if (r != null) {
11752 Intent.FilterComparison filter
11753 = new Intent.FilterComparison(intent);
11754 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011755 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011756 + " at " + b + ": apps="
11757 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011758
11759 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011760 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011761 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011762 // Applications have already bound since the last
11763 // unbind, so just rebind right here.
11764 requestServiceBindingLocked(r, b, true);
11765 } else {
11766 // Note to tell the service the next time there is
11767 // a new client.
11768 b.doRebind = true;
11769 }
11770 }
11771
Per Edelberg78f9fff2010-08-30 20:01:35 +020011772 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011773
11774 Binder.restoreCallingIdentity(origId);
11775 }
11776 }
11777 }
11778
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011779 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011780 synchronized(this) {
11781 if (!(token instanceof ServiceRecord)) {
11782 throw new IllegalArgumentException("Invalid service token");
11783 }
11784 ServiceRecord r = (ServiceRecord)token;
11785 boolean inStopping = mStoppingServices.contains(token);
11786 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011787 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011788 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011789 + " with incorrect token: given " + token
11790 + ", expected " + r);
11791 return;
11792 }
11793
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011794 if (type == 1) {
11795 // This is a call from a service start... take care of
11796 // book-keeping.
11797 r.callStart = true;
11798 switch (res) {
11799 case Service.START_STICKY_COMPATIBILITY:
11800 case Service.START_STICKY: {
11801 // We are done with the associated start arguments.
11802 r.findDeliveredStart(startId, true);
11803 // Don't stop if killed.
11804 r.stopIfKilled = false;
11805 break;
11806 }
11807 case Service.START_NOT_STICKY: {
11808 // We are done with the associated start arguments.
11809 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011810 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011811 // There is no more work, and this service
11812 // doesn't want to hang around if killed.
11813 r.stopIfKilled = true;
11814 }
11815 break;
11816 }
11817 case Service.START_REDELIVER_INTENT: {
11818 // We'll keep this item until they explicitly
11819 // call stop for it, but keep track of the fact
11820 // that it was delivered.
11821 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11822 if (si != null) {
11823 si.deliveryCount = 0;
11824 si.doneExecutingCount++;
11825 // Don't stop if killed.
11826 r.stopIfKilled = true;
11827 }
11828 break;
11829 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011830 case Service.START_TASK_REMOVED_COMPLETE: {
11831 // Special processing for onTaskRemoved(). Don't
11832 // impact normal onStartCommand() processing.
11833 r.findDeliveredStart(startId, true);
11834 break;
11835 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011836 default:
11837 throw new IllegalArgumentException(
11838 "Unknown service start result: " + res);
11839 }
11840 if (res == Service.START_STICKY_COMPATIBILITY) {
11841 r.callStart = false;
11842 }
11843 }
11844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011845 final long origId = Binder.clearCallingIdentity();
11846 serviceDoneExecutingLocked(r, inStopping);
11847 Binder.restoreCallingIdentity(origId);
11848 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011849 Slog.w(TAG, "Done executing unknown service from pid "
11850 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011851 }
11852 }
11853 }
11854
11855 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011856 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11857 + ": nesting=" + r.executeNesting
11858 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011859 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011860 r.executeNesting--;
11861 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011862 if (DEBUG_SERVICE) Slog.v(TAG,
11863 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011864 r.app.executingServices.remove(r);
11865 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011866 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11867 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011868 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11869 }
11870 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011871 if (DEBUG_SERVICE) Slog.v(TAG,
11872 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011873 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011874 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011875 }
11876 updateOomAdjLocked(r.app);
11877 }
11878 }
11879
11880 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011881 String anrMessage = null;
11882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011883 synchronized(this) {
11884 if (proc.executingServices.size() == 0 || proc.thread == null) {
11885 return;
11886 }
11887 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11888 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11889 ServiceRecord timeout = null;
11890 long nextTime = 0;
11891 while (it.hasNext()) {
11892 ServiceRecord sr = it.next();
11893 if (sr.executingStart < maxTime) {
11894 timeout = sr;
11895 break;
11896 }
11897 if (sr.executingStart > nextTime) {
11898 nextTime = sr.executingStart;
11899 }
11900 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011901 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011902 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011903 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011904 } else {
11905 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11906 msg.obj = proc;
11907 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11908 }
11909 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011910
11911 if (anrMessage != null) {
11912 appNotResponding(proc, null, null, anrMessage);
11913 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011914 }
11915
11916 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011917 // BACKUP AND RESTORE
11918 // =========================================================
11919
11920 // Cause the target app to be launched if necessary and its backup agent
11921 // instantiated. The backup agent will invoke backupAgentCreated() on the
11922 // activity manager to announce its creation.
11923 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011924 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011925 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11926
11927 synchronized(this) {
11928 // !!! TODO: currently no check here that we're already bound
11929 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11930 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11931 synchronized (stats) {
11932 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11933 }
11934
Dianne Hackborne7f97212011-02-24 14:40:20 -080011935 // Backup agent is now in use, its package can't be stopped.
11936 try {
11937 AppGlobals.getPackageManager().setPackageStoppedState(
11938 app.packageName, false);
11939 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011940 } catch (IllegalArgumentException e) {
11941 Slog.w(TAG, "Failed trying to unstop package "
11942 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011943 }
11944
Christopher Tate181fafa2009-05-14 11:12:14 -070011945 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011946 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11947 ? new ComponentName(app.packageName, app.backupAgentName)
11948 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011949 // startProcessLocked() returns existing proc's record if it's already running
11950 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011951 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011952 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011953 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011954 return false;
11955 }
11956
11957 r.app = proc;
11958 mBackupTarget = r;
11959 mBackupAppName = app.packageName;
11960
Christopher Tate6fa95972009-06-05 18:43:55 -070011961 // Try not to kill the process during backup
11962 updateOomAdjLocked(proc);
11963
Christopher Tate181fafa2009-05-14 11:12:14 -070011964 // If the process is already attached, schedule the creation of the backup agent now.
11965 // If it is not yet live, this will be done when it attaches to the framework.
11966 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011967 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011968 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011969 proc.thread.scheduleCreateBackupAgent(app,
11970 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011971 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011972 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011973 }
11974 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011975 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011976 }
11977 // Invariants: at this point, the target app process exists and the application
11978 // is either already running or in the process of coming up. mBackupTarget and
11979 // mBackupAppName describe the app, so that when it binds back to the AM we
11980 // know that it's scheduled for a backup-agent operation.
11981 }
11982
11983 return true;
11984 }
11985
11986 // A backup agent has just come up
11987 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011988 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011989 + " = " + agent);
11990
11991 synchronized(this) {
11992 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011993 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011994 return;
11995 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011996 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011997
Dianne Hackborn06740692010-09-22 22:46:21 -070011998 long oldIdent = Binder.clearCallingIdentity();
11999 try {
12000 IBackupManager bm = IBackupManager.Stub.asInterface(
12001 ServiceManager.getService(Context.BACKUP_SERVICE));
12002 bm.agentConnected(agentPackageName, agent);
12003 } catch (RemoteException e) {
12004 // can't happen; the backup manager service is local
12005 } catch (Exception e) {
12006 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12007 e.printStackTrace();
12008 } finally {
12009 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070012010 }
12011 }
12012
12013 // done with this agent
12014 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012015 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070012016 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012017 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070012018 return;
12019 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012020
12021 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070012022 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012023 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070012024 return;
12025 }
12026
Christopher Tate181fafa2009-05-14 11:12:14 -070012027 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012028 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070012029 return;
12030 }
12031
Christopher Tate6fa95972009-06-05 18:43:55 -070012032 ProcessRecord proc = mBackupTarget.app;
12033 mBackupTarget = null;
12034 mBackupAppName = null;
12035
12036 // Not backing this app up any more; reset its OOM adjustment
12037 updateOomAdjLocked(proc);
12038
Christopher Tatec7b31e32009-06-10 15:49:30 -070012039 // If the app crashed during backup, 'thread' will be null here
12040 if (proc.thread != null) {
12041 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012042 proc.thread.scheduleDestroyBackupAgent(appInfo,
12043 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070012044 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012045 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070012046 e.printStackTrace();
12047 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012048 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012049 }
12050 }
12051 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012052 // BROADCASTS
12053 // =========================================================
12054
Josh Bartel7f208742010-02-25 11:01:44 -060012055 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012056 List cur) {
12057 final ContentResolver resolver = mContext.getContentResolver();
12058 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
12059 if (list == null) {
12060 return cur;
12061 }
12062 int N = list.size();
12063 for (int i=0; i<N; i++) {
12064 Intent intent = list.get(i);
12065 if (filter.match(resolver, intent, true, TAG) >= 0) {
12066 if (cur == null) {
12067 cur = new ArrayList<Intent>();
12068 }
12069 cur.add(intent);
12070 }
12071 }
12072 return cur;
12073 }
12074
12075 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012076 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012077 + mBroadcastsScheduled);
12078
12079 if (mBroadcastsScheduled) {
12080 return;
12081 }
12082 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
12083 mBroadcastsScheduled = true;
12084 }
12085
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012086 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012087 IIntentReceiver receiver, IntentFilter filter, String permission) {
12088 synchronized(this) {
12089 ProcessRecord callerApp = null;
12090 if (caller != null) {
12091 callerApp = getRecordForAppLocked(caller);
12092 if (callerApp == null) {
12093 throw new SecurityException(
12094 "Unable to find app for caller " + caller
12095 + " (pid=" + Binder.getCallingPid()
12096 + ") when registering receiver " + receiver);
12097 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012098 if (callerApp.info.uid != Process.SYSTEM_UID &&
12099 !callerApp.pkgList.contains(callerPackage)) {
12100 throw new SecurityException("Given caller package " + callerPackage
12101 + " is not running in process " + callerApp);
12102 }
12103 } else {
12104 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012105 }
12106
12107 List allSticky = null;
12108
12109 // Look for any matching sticky broadcasts...
12110 Iterator actions = filter.actionsIterator();
12111 if (actions != null) {
12112 while (actions.hasNext()) {
12113 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060012114 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012115 }
12116 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060012117 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012118 }
12119
12120 // The first sticky in the list is returned directly back to
12121 // the client.
12122 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12123
Joe Onorato8a9b2202010-02-26 18:56:32 -080012124 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012125 + ": " + sticky);
12126
12127 if (receiver == null) {
12128 return sticky;
12129 }
12130
12131 ReceiverList rl
12132 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12133 if (rl == null) {
12134 rl = new ReceiverList(this, callerApp,
12135 Binder.getCallingPid(),
12136 Binder.getCallingUid(), receiver);
12137 if (rl.app != null) {
12138 rl.app.receivers.add(rl);
12139 } else {
12140 try {
12141 receiver.asBinder().linkToDeath(rl, 0);
12142 } catch (RemoteException e) {
12143 return sticky;
12144 }
12145 rl.linkedToDeath = true;
12146 }
12147 mRegisteredReceivers.put(receiver.asBinder(), rl);
12148 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012149 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012150 rl.add(bf);
12151 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012152 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012153 }
12154 mReceiverResolver.addFilter(bf);
12155
12156 // Enqueue broadcasts for all existing stickies that match
12157 // this filter.
12158 if (allSticky != null) {
12159 ArrayList receivers = new ArrayList();
12160 receivers.add(bf);
12161
12162 int N = allSticky.size();
12163 for (int i=0; i<N; i++) {
12164 Intent intent = (Intent)allSticky.get(i);
12165 BroadcastRecord r = new BroadcastRecord(intent, null,
12166 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012167 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012168 if (mParallelBroadcasts.size() == 0) {
12169 scheduleBroadcastsLocked();
12170 }
12171 mParallelBroadcasts.add(r);
12172 }
12173 }
12174
12175 return sticky;
12176 }
12177 }
12178
12179 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012180 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012181
12182 boolean doNext = false;
12183
12184 synchronized(this) {
12185 ReceiverList rl
12186 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12187 if (rl != null) {
12188 if (rl.curBroadcast != null) {
12189 BroadcastRecord r = rl.curBroadcast;
12190 doNext = finishReceiverLocked(
12191 receiver.asBinder(), r.resultCode, r.resultData,
12192 r.resultExtras, r.resultAbort, true);
12193 }
12194
12195 if (rl.app != null) {
12196 rl.app.receivers.remove(rl);
12197 }
12198 removeReceiverLocked(rl);
12199 if (rl.linkedToDeath) {
12200 rl.linkedToDeath = false;
12201 rl.receiver.asBinder().unlinkToDeath(rl, 0);
12202 }
12203 }
12204 }
12205
12206 if (!doNext) {
12207 return;
12208 }
12209
12210 final long origId = Binder.clearCallingIdentity();
12211 processNextBroadcast(false);
12212 trimApplications();
12213 Binder.restoreCallingIdentity(origId);
12214 }
12215
12216 void removeReceiverLocked(ReceiverList rl) {
12217 mRegisteredReceivers.remove(rl.receiver.asBinder());
12218 int N = rl.size();
12219 for (int i=0; i<N; i++) {
12220 mReceiverResolver.removeFilter(rl.get(i));
12221 }
12222 }
12223
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012224 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12225 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12226 ProcessRecord r = mLruProcesses.get(i);
12227 if (r.thread != null) {
12228 try {
12229 r.thread.dispatchPackageBroadcast(cmd, packages);
12230 } catch (RemoteException ex) {
12231 }
12232 }
12233 }
12234 }
12235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012236 private final int broadcastIntentLocked(ProcessRecord callerApp,
12237 String callerPackage, Intent intent, String resolvedType,
12238 IIntentReceiver resultTo, int resultCode, String resultData,
12239 Bundle map, String requiredPermission,
12240 boolean ordered, boolean sticky, int callingPid, int callingUid) {
12241 intent = new Intent(intent);
12242
Dianne Hackborne7f97212011-02-24 14:40:20 -080012243 // By default broadcasts do not go to stopped apps.
12244 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12245
Joe Onorato8a9b2202010-02-26 18:56:32 -080012246 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012247 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
12248 + " ordered=" + ordered);
12249 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012250 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012251 }
12252
12253 // Handle special intents: if this broadcast is from the package
12254 // manager about a package being removed, we need to remove all of
12255 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012256 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012257 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012258 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12259 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012260 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012261 || uidRemoved) {
12262 if (checkComponentPermission(
12263 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012264 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012265 == PackageManager.PERMISSION_GRANTED) {
12266 if (uidRemoved) {
12267 final Bundle intentExtras = intent.getExtras();
12268 final int uid = intentExtras != null
12269 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12270 if (uid >= 0) {
12271 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12272 synchronized (bs) {
12273 bs.removeUidStatsLocked(uid);
12274 }
12275 }
12276 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012277 // If resources are unvailble just force stop all
12278 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012279 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012280 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12281 if (list != null && (list.length > 0)) {
12282 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070012283 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012284 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012285 sendPackageBroadcastLocked(
12286 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012287 }
12288 } else {
12289 Uri data = intent.getData();
12290 String ssp;
12291 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12292 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12293 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070012294 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070012295 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012296 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012297 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12298 new String[] {ssp});
12299 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012300 }
12301 }
12302 }
12303 } else {
12304 String msg = "Permission Denial: " + intent.getAction()
12305 + " broadcast from " + callerPackage + " (pid=" + callingPid
12306 + ", uid=" + callingUid + ")"
12307 + " requires "
12308 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012309 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012310 throw new SecurityException(msg);
12311 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012312
12313 // Special case for adding a package: by default turn on compatibility
12314 // mode.
12315 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070012316 Uri data = intent.getData();
12317 String ssp;
12318 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12319 mCompatModePackages.handlePackageAddedLocked(ssp,
12320 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012321 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012322 }
12323
12324 /*
12325 * If this is the time zone changed action, queue up a message that will reset the timezone
12326 * of all currently running processes. This message will get queued up before the broadcast
12327 * happens.
12328 */
12329 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12330 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12331 }
12332
Robert Greenwalt03595d02010-11-02 14:08:23 -070012333 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12334 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12335 }
12336
Robert Greenwalt434203a2010-10-11 16:00:27 -070012337 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12338 ProxyProperties proxy = intent.getParcelableExtra("proxy");
12339 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12340 }
12341
Dianne Hackborn854060af2009-07-09 18:14:31 -070012342 /*
12343 * Prevent non-system code (defined here to be non-persistent
12344 * processes) from sending protected broadcasts.
12345 */
12346 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12347 || callingUid == Process.SHELL_UID || callingUid == 0) {
12348 // Always okay.
12349 } else if (callerApp == null || !callerApp.persistent) {
12350 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012351 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070012352 intent.getAction())) {
12353 String msg = "Permission Denial: not allowed to send broadcast "
12354 + intent.getAction() + " from pid="
12355 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012356 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012357 throw new SecurityException(msg);
12358 }
12359 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012360 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012361 return BROADCAST_SUCCESS;
12362 }
12363 }
12364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012365 // Add to the sticky list if requested.
12366 if (sticky) {
12367 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12368 callingPid, callingUid)
12369 != PackageManager.PERMISSION_GRANTED) {
12370 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12371 + callingPid + ", uid=" + callingUid
12372 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012373 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012374 throw new SecurityException(msg);
12375 }
12376 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012377 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012378 + " and enforce permission " + requiredPermission);
12379 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12380 }
12381 if (intent.getComponent() != null) {
12382 throw new SecurityException(
12383 "Sticky broadcasts can't target a specific component");
12384 }
12385 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12386 if (list == null) {
12387 list = new ArrayList<Intent>();
12388 mStickyBroadcasts.put(intent.getAction(), list);
12389 }
12390 int N = list.size();
12391 int i;
12392 for (i=0; i<N; i++) {
12393 if (intent.filterEquals(list.get(i))) {
12394 // This sticky already exists, replace it.
12395 list.set(i, new Intent(intent));
12396 break;
12397 }
12398 }
12399 if (i >= N) {
12400 list.add(new Intent(intent));
12401 }
12402 }
12403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012404 // Figure out who all will receive this broadcast.
12405 List receivers = null;
12406 List<BroadcastFilter> registeredReceivers = null;
12407 try {
12408 if (intent.getComponent() != null) {
12409 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012410 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070012411 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012412 if (ai != null) {
12413 receivers = new ArrayList();
12414 ResolveInfo ri = new ResolveInfo();
12415 ri.activityInfo = ai;
12416 receivers.add(ri);
12417 }
12418 } else {
12419 // Need to resolve the intent to interested receivers...
12420 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12421 == 0) {
12422 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012423 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012424 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012425 }
Mihai Preda074edef2009-05-18 17:13:31 +020012426 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012427 }
12428 } catch (RemoteException ex) {
12429 // pm is in same process, this will never happen.
12430 }
12431
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012432 final boolean replacePending =
12433 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12434
Joe Onorato8a9b2202010-02-26 18:56:32 -080012435 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012436 + " replacePending=" + replacePending);
12437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012438 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12439 if (!ordered && NR > 0) {
12440 // If we are not serializing this broadcast, then send the
12441 // registered receivers separately so they don't wait for the
12442 // components to be launched.
12443 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12444 callerPackage, callingPid, callingUid, requiredPermission,
12445 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012446 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012447 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012448 TAG, "Enqueueing parallel broadcast " + r
12449 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012450 boolean replaced = false;
12451 if (replacePending) {
12452 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
12453 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012454 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012455 "***** DROPPING PARALLEL: " + intent);
12456 mParallelBroadcasts.set(i, r);
12457 replaced = true;
12458 break;
12459 }
12460 }
12461 }
12462 if (!replaced) {
12463 mParallelBroadcasts.add(r);
12464 scheduleBroadcastsLocked();
12465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012466 registeredReceivers = null;
12467 NR = 0;
12468 }
12469
12470 // Merge into one list.
12471 int ir = 0;
12472 if (receivers != null) {
12473 // A special case for PACKAGE_ADDED: do not allow the package
12474 // being added to see this broadcast. This prevents them from
12475 // using this as a back door to get run as soon as they are
12476 // installed. Maybe in the future we want to have a special install
12477 // broadcast or such for apps, but we'd like to deliberately make
12478 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012479 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012480 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
12481 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
12482 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012483 Uri data = intent.getData();
12484 if (data != null) {
12485 String pkgName = data.getSchemeSpecificPart();
12486 if (pkgName != null) {
12487 skipPackages = new String[] { pkgName };
12488 }
12489 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012490 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012491 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070012492 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012493 if (skipPackages != null && (skipPackages.length > 0)) {
12494 for (String skipPackage : skipPackages) {
12495 if (skipPackage != null) {
12496 int NT = receivers.size();
12497 for (int it=0; it<NT; it++) {
12498 ResolveInfo curt = (ResolveInfo)receivers.get(it);
12499 if (curt.activityInfo.packageName.equals(skipPackage)) {
12500 receivers.remove(it);
12501 it--;
12502 NT--;
12503 }
12504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012505 }
12506 }
12507 }
12508
12509 int NT = receivers != null ? receivers.size() : 0;
12510 int it = 0;
12511 ResolveInfo curt = null;
12512 BroadcastFilter curr = null;
12513 while (it < NT && ir < NR) {
12514 if (curt == null) {
12515 curt = (ResolveInfo)receivers.get(it);
12516 }
12517 if (curr == null) {
12518 curr = registeredReceivers.get(ir);
12519 }
12520 if (curr.getPriority() >= curt.priority) {
12521 // Insert this broadcast record into the final list.
12522 receivers.add(it, curr);
12523 ir++;
12524 curr = null;
12525 it++;
12526 NT++;
12527 } else {
12528 // Skip to the next ResolveInfo in the final list.
12529 it++;
12530 curt = null;
12531 }
12532 }
12533 }
12534 while (ir < NR) {
12535 if (receivers == null) {
12536 receivers = new ArrayList();
12537 }
12538 receivers.add(registeredReceivers.get(ir));
12539 ir++;
12540 }
12541
12542 if ((receivers != null && receivers.size() > 0)
12543 || resultTo != null) {
12544 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12545 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012546 receivers, resultTo, resultCode, resultData, map, ordered,
12547 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012548 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012549 TAG, "Enqueueing ordered broadcast " + r
12550 + ": prev had " + mOrderedBroadcasts.size());
12551 if (DEBUG_BROADCAST) {
12552 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012553 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012554 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012555 boolean replaced = false;
12556 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012557 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012558 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012559 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012560 "***** DROPPING ORDERED: " + intent);
12561 mOrderedBroadcasts.set(i, r);
12562 replaced = true;
12563 break;
12564 }
12565 }
12566 }
12567 if (!replaced) {
12568 mOrderedBroadcasts.add(r);
12569 scheduleBroadcastsLocked();
12570 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012571 }
12572
12573 return BROADCAST_SUCCESS;
12574 }
12575
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012576 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012577 // Refuse possible leaked file descriptors
12578 if (intent != null && intent.hasFileDescriptors() == true) {
12579 throw new IllegalArgumentException("File descriptors passed in Intent");
12580 }
12581
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012582 int flags = intent.getFlags();
12583
12584 if (!mProcessesReady) {
12585 // if the caller really truly claims to know what they're doing, go
12586 // ahead and allow the broadcast without launching any receivers
12587 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12588 intent = new Intent(intent);
12589 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12590 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12591 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12592 + " before boot completion");
12593 throw new IllegalStateException("Cannot broadcast before boot completed");
12594 }
12595 }
12596
12597 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12598 throw new IllegalArgumentException(
12599 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12600 }
12601
12602 return intent;
12603 }
12604
12605 public final int broadcastIntent(IApplicationThread caller,
12606 Intent intent, String resolvedType, IIntentReceiver resultTo,
12607 int resultCode, String resultData, Bundle map,
12608 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012609 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012610 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012612 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12613 final int callingPid = Binder.getCallingPid();
12614 final int callingUid = Binder.getCallingUid();
12615 final long origId = Binder.clearCallingIdentity();
12616 int res = broadcastIntentLocked(callerApp,
12617 callerApp != null ? callerApp.info.packageName : null,
12618 intent, resolvedType, resultTo,
12619 resultCode, resultData, map, requiredPermission, serialized,
12620 sticky, callingPid, callingUid);
12621 Binder.restoreCallingIdentity(origId);
12622 return res;
12623 }
12624 }
12625
12626 int broadcastIntentInPackage(String packageName, int uid,
12627 Intent intent, String resolvedType, IIntentReceiver resultTo,
12628 int resultCode, String resultData, Bundle map,
12629 String requiredPermission, boolean serialized, boolean sticky) {
12630 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012631 intent = verifyBroadcastLocked(intent);
12632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012633 final long origId = Binder.clearCallingIdentity();
12634 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12635 resultTo, resultCode, resultData, map, requiredPermission,
12636 serialized, sticky, -1, uid);
12637 Binder.restoreCallingIdentity(origId);
12638 return res;
12639 }
12640 }
12641
12642 public final void unbroadcastIntent(IApplicationThread caller,
12643 Intent intent) {
12644 // Refuse possible leaked file descriptors
12645 if (intent != null && intent.hasFileDescriptors() == true) {
12646 throw new IllegalArgumentException("File descriptors passed in Intent");
12647 }
12648
12649 synchronized(this) {
12650 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12651 != PackageManager.PERMISSION_GRANTED) {
12652 String msg = "Permission Denial: unbroadcastIntent() from pid="
12653 + Binder.getCallingPid()
12654 + ", uid=" + Binder.getCallingUid()
12655 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012656 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012657 throw new SecurityException(msg);
12658 }
12659 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12660 if (list != null) {
12661 int N = list.size();
12662 int i;
12663 for (i=0; i<N; i++) {
12664 if (intent.filterEquals(list.get(i))) {
12665 list.remove(i);
12666 break;
12667 }
12668 }
12669 }
12670 }
12671 }
12672
12673 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12674 String resultData, Bundle resultExtras, boolean resultAbort,
12675 boolean explicit) {
12676 if (mOrderedBroadcasts.size() == 0) {
12677 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012678 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012679 }
12680 return false;
12681 }
12682 BroadcastRecord r = mOrderedBroadcasts.get(0);
12683 if (r.receiver == null) {
12684 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012685 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012686 }
12687 return false;
12688 }
12689 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012690 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012691 return false;
12692 }
12693 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012694 r.state = BroadcastRecord.IDLE;
12695 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012696 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012697 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012698 }
12699 }
12700 r.receiver = null;
12701 r.intent.setComponent(null);
12702 if (r.curApp != null) {
12703 r.curApp.curReceiver = null;
12704 }
12705 if (r.curFilter != null) {
12706 r.curFilter.receiverList.curBroadcast = null;
12707 }
12708 r.curFilter = null;
12709 r.curApp = null;
12710 r.curComponent = null;
12711 r.curReceiver = null;
12712 mPendingBroadcast = null;
12713
12714 r.resultCode = resultCode;
12715 r.resultData = resultData;
12716 r.resultExtras = resultExtras;
12717 r.resultAbort = resultAbort;
12718
12719 // We will process the next receiver right now if this is finishing
12720 // an app receiver (which is always asynchronous) or after we have
12721 // come back from calling a receiver.
12722 return state == BroadcastRecord.APP_RECEIVE
12723 || state == BroadcastRecord.CALL_DONE_RECEIVE;
12724 }
12725
12726 public void finishReceiver(IBinder who, int resultCode, String resultData,
12727 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012728 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012729
12730 // Refuse possible leaked file descriptors
12731 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12732 throw new IllegalArgumentException("File descriptors passed in Bundle");
12733 }
12734
12735 boolean doNext;
12736
12737 final long origId = Binder.clearCallingIdentity();
12738
12739 synchronized(this) {
12740 doNext = finishReceiverLocked(
12741 who, resultCode, resultData, resultExtras, resultAbort, true);
12742 }
12743
12744 if (doNext) {
12745 processNextBroadcast(false);
12746 }
12747 trimApplications();
12748
12749 Binder.restoreCallingIdentity(origId);
12750 }
12751
Jeff Brown4d94a762010-09-23 11:33:28 -070012752 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012753 if (r.nextReceiver > 0) {
12754 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12755 if (curReceiver instanceof BroadcastFilter) {
12756 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012757 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012758 System.identityHashCode(r),
12759 r.intent.getAction(),
12760 r.nextReceiver - 1,
12761 System.identityHashCode(bf));
12762 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012763 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012764 System.identityHashCode(r),
12765 r.intent.getAction(),
12766 r.nextReceiver - 1,
12767 ((ResolveInfo)curReceiver).toString());
12768 }
12769 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012770 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012771 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012772 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012773 System.identityHashCode(r),
12774 r.intent.getAction(),
12775 r.nextReceiver,
12776 "NONE");
12777 }
12778 }
12779
Jeff Brown4d94a762010-09-23 11:33:28 -070012780 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12781 if (! mPendingBroadcastTimeoutMessage) {
12782 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12783 mHandler.sendMessageAtTime(msg, timeoutTime);
12784 mPendingBroadcastTimeoutMessage = true;
12785 }
12786 }
12787
12788 private final void cancelBroadcastTimeoutLocked() {
12789 if (mPendingBroadcastTimeoutMessage) {
12790 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12791 mPendingBroadcastTimeoutMessage = false;
12792 }
12793 }
12794
12795 private final void broadcastTimeoutLocked(boolean fromMsg) {
12796 if (fromMsg) {
12797 mPendingBroadcastTimeoutMessage = false;
12798 }
12799
12800 if (mOrderedBroadcasts.size() == 0) {
12801 return;
12802 }
12803
12804 long now = SystemClock.uptimeMillis();
12805 BroadcastRecord r = mOrderedBroadcasts.get(0);
12806 if (fromMsg) {
12807 if (mDidDexOpt) {
12808 // Delay timeouts until dexopt finishes.
12809 mDidDexOpt = false;
12810 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12811 setBroadcastTimeoutLocked(timeoutTime);
12812 return;
12813 }
12814 if (! mProcessesReady) {
12815 // Only process broadcast timeouts if the system is ready. That way
12816 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12817 // to do heavy lifting for system up.
12818 return;
12819 }
12820
12821 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12822 if (timeoutTime > now) {
12823 // We can observe premature timeouts because we do not cancel and reset the
12824 // broadcast timeout message after each receiver finishes. Instead, we set up
12825 // an initial timeout then kick it down the road a little further as needed
12826 // when it expires.
12827 if (DEBUG_BROADCAST) Slog.v(TAG,
12828 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12829 + timeoutTime);
12830 setBroadcastTimeoutLocked(timeoutTime);
12831 return;
12832 }
12833 }
12834
12835 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12836 + ", started " + (now - r.receiverTime) + "ms ago");
12837 r.receiverTime = now;
12838 r.anrCount++;
12839
12840 // Current receiver has passed its expiration date.
12841 if (r.nextReceiver <= 0) {
12842 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12843 return;
12844 }
12845
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012846 ProcessRecord app = null;
12847 String anrMessage = null;
12848
Jeff Brown4d94a762010-09-23 11:33:28 -070012849 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12850 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12851 logBroadcastReceiverDiscardLocked(r);
12852 if (curReceiver instanceof BroadcastFilter) {
12853 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12854 if (bf.receiverList.pid != 0
12855 && bf.receiverList.pid != MY_PID) {
12856 synchronized (this.mPidsSelfLocked) {
12857 app = this.mPidsSelfLocked.get(
12858 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012860 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012861 } else {
12862 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012863 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012864
Jeff Brown4d94a762010-09-23 11:33:28 -070012865 if (app != null) {
12866 anrMessage = "Broadcast of " + r.intent.toString();
12867 }
12868
12869 if (mPendingBroadcast == r) {
12870 mPendingBroadcast = null;
12871 }
12872
12873 // Move on to the next receiver.
12874 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12875 r.resultExtras, r.resultAbort, true);
12876 scheduleBroadcastsLocked();
12877
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012878 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012879 // Post the ANR to the handler since we do not want to process ANRs while
12880 // potentially holding our lock.
12881 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012883 }
12884
12885 private final void processCurBroadcastLocked(BroadcastRecord r,
12886 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012887 if (DEBUG_BROADCAST) Slog.v(TAG,
12888 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012889 if (app.thread == null) {
12890 throw new RemoteException();
12891 }
12892 r.receiver = app.thread.asBinder();
12893 r.curApp = app;
12894 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012895 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012896
12897 // Tell the application to launch this receiver.
12898 r.intent.setComponent(r.curComponent);
12899
12900 boolean started = false;
12901 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012902 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012903 "Delivering to component " + r.curComponent
12904 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012905 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012906 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012907 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012908 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012909 if (DEBUG_BROADCAST) Slog.v(TAG,
12910 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012911 started = true;
12912 } finally {
12913 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012914 if (DEBUG_BROADCAST) Slog.v(TAG,
12915 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012916 r.receiver = null;
12917 r.curApp = null;
12918 app.curReceiver = null;
12919 }
12920 }
12921
12922 }
12923
Jeff Brown4d94a762010-09-23 11:33:28 -070012924 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012925 Intent intent, int resultCode, String data, Bundle extras,
12926 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012927 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012928 if (app != null && app.thread != null) {
12929 // If we have an app thread, do the call through that so it is
12930 // correctly ordered with other one-way calls.
12931 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012932 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012933 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012934 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012935 }
12936 }
12937
Jeff Brown4d94a762010-09-23 11:33:28 -070012938 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012939 BroadcastFilter filter, boolean ordered) {
12940 boolean skip = false;
12941 if (filter.requiredPermission != null) {
12942 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012943 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012944 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012945 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012946 + r.intent.toString()
12947 + " from " + r.callerPackage + " (pid="
12948 + r.callingPid + ", uid=" + r.callingUid + ")"
12949 + " requires " + filter.requiredPermission
12950 + " due to registered receiver " + filter);
12951 skip = true;
12952 }
12953 }
12954 if (r.requiredPermission != null) {
12955 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012956 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012957 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012958 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012959 + r.intent.toString()
12960 + " to " + filter.receiverList.app
12961 + " (pid=" + filter.receiverList.pid
12962 + ", uid=" + filter.receiverList.uid + ")"
12963 + " requires " + r.requiredPermission
12964 + " due to sender " + r.callerPackage
12965 + " (uid " + r.callingUid + ")");
12966 skip = true;
12967 }
12968 }
12969
12970 if (!skip) {
12971 // If this is not being sent as an ordered broadcast, then we
12972 // don't want to touch the fields that keep track of the current
12973 // state of ordered broadcasts.
12974 if (ordered) {
12975 r.receiver = filter.receiverList.receiver.asBinder();
12976 r.curFilter = filter;
12977 filter.receiverList.curBroadcast = r;
12978 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012979 if (filter.receiverList.app != null) {
12980 // Bump hosting application to no longer be in background
12981 // scheduling class. Note that we can't do that if there
12982 // isn't an app... but we can only be in that case for
12983 // things that directly call the IActivityManager API, which
12984 // are already core system stuff so don't matter for this.
12985 r.curApp = filter.receiverList.app;
12986 filter.receiverList.app.curReceiver = r;
12987 updateOomAdjLocked();
12988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012989 }
12990 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012991 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012992 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012993 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012994 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012995 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012996 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012997 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012998 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012999 if (ordered) {
13000 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
13001 }
13002 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013003 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013004 if (ordered) {
13005 r.receiver = null;
13006 r.curFilter = null;
13007 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013008 if (filter.receiverList.app != null) {
13009 filter.receiverList.app.curReceiver = null;
13010 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013011 }
13012 }
13013 }
13014 }
13015
Dianne Hackborn12527f92009-11-11 17:39:50 -080013016 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
13017 if (r.callingUid < 0) {
13018 // This was from a registerReceiver() call; ignore it.
13019 return;
13020 }
13021 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
13022 MAX_BROADCAST_HISTORY-1);
13023 r.finishTime = SystemClock.uptimeMillis();
13024 mBroadcastHistory[0] = r;
13025 }
13026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013027 private final void processNextBroadcast(boolean fromMsg) {
13028 synchronized(this) {
13029 BroadcastRecord r;
13030
Joe Onorato8a9b2202010-02-26 18:56:32 -080013031 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013032 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013033 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013034
13035 updateCpuStats();
13036
13037 if (fromMsg) {
13038 mBroadcastsScheduled = false;
13039 }
13040
13041 // First, deliver any non-serialized broadcasts right away.
13042 while (mParallelBroadcasts.size() > 0) {
13043 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080013044 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070013045 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013046 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013047 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013048 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013049 for (int i=0; i<N; i++) {
13050 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013051 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013052 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013053 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070013054 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013055 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080013056 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013057 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013058 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013059 }
13060
13061 // Now take care of the next serialized one...
13062
13063 // If we are waiting for a process to come up to handle the next
13064 // broadcast, then do nothing at this point. Just in case, we
13065 // check that the process we're waiting for still exists.
13066 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070013067 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013068 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070013069 + mPendingBroadcast.curApp);
13070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013071
13072 boolean isDead;
13073 synchronized (mPidsSelfLocked) {
13074 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
13075 }
13076 if (!isDead) {
13077 // It's still alive, so keep waiting
13078 return;
13079 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013080 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013081 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013082 mPendingBroadcast.state = BroadcastRecord.IDLE;
13083 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013084 mPendingBroadcast = null;
13085 }
13086 }
13087
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013088 boolean looped = false;
13089
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013090 do {
13091 if (mOrderedBroadcasts.size() == 0) {
13092 // No more broadcasts pending, so all done!
13093 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013094 if (looped) {
13095 // If we had finished the last ordered broadcast, then
13096 // make sure all processes have correct oom and sched
13097 // adjustments.
13098 updateOomAdjLocked();
13099 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013100 return;
13101 }
13102 r = mOrderedBroadcasts.get(0);
13103 boolean forceReceive = false;
13104
13105 // Ensure that even if something goes awry with the timeout
13106 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050013107 // and continue to make progress.
13108 //
13109 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070013110 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050013111 // one time heavy lifting after system upgrades and can take
13112 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013113 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013114 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050013115 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013116 if ((numReceivers > 0) &&
13117 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013118 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013119 + " now=" + now
13120 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080013121 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013122 + " intent=" + r.intent
13123 + " numReceivers=" + numReceivers
13124 + " nextReceiver=" + r.nextReceiver
13125 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070013126 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013127 forceReceive = true;
13128 r.state = BroadcastRecord.IDLE;
13129 }
13130 }
13131
13132 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013133 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013134 "processNextBroadcast() called when not idle (state="
13135 + r.state + ")");
13136 return;
13137 }
13138
13139 if (r.receivers == null || r.nextReceiver >= numReceivers
13140 || r.resultAbort || forceReceive) {
13141 // No more receivers for this broadcast! Send the final
13142 // result if requested...
13143 if (r.resultTo != null) {
13144 try {
13145 if (DEBUG_BROADCAST) {
13146 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013147 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013148 + " seq=" + seq + " app=" + r.callerApp);
13149 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013150 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013151 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070013152 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020013153 // Set this to null so that the reference
13154 // (local and remote) isnt kept in the mBroadcastHistory.
13155 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013156 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013157 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013158 }
13159 }
13160
Joe Onorato8a9b2202010-02-26 18:56:32 -080013161 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070013162 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013163
Joe Onorato8a9b2202010-02-26 18:56:32 -080013164 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013165 + r);
13166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013167 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080013168 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013169 mOrderedBroadcasts.remove(0);
13170 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013171 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013172 continue;
13173 }
13174 } while (r == null);
13175
13176 // Get the next receiver...
13177 int recIdx = r.nextReceiver++;
13178
13179 // Keep track of when this receiver started, and make sure there
13180 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080013181 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013182 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080013183 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070013184 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013185 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070013186 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070013187 }
13188 if (! mPendingBroadcastTimeoutMessage) {
13189 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013190 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070013191 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
13192 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013193 }
13194
13195 Object nextReceiver = r.receivers.get(recIdx);
13196 if (nextReceiver instanceof BroadcastFilter) {
13197 // Simple case: this is a registered receiver who gets
13198 // a direct call.
13199 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013200 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013201 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013202 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070013203 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013204 if (r.receiver == null || !r.ordered) {
13205 // The receiver has already finished, so schedule to
13206 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013207 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
13208 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013209 r.state = BroadcastRecord.IDLE;
13210 scheduleBroadcastsLocked();
13211 }
13212 return;
13213 }
13214
13215 // Hard case: need to instantiate the receiver, possibly
13216 // starting its application process to host it.
13217
13218 ResolveInfo info =
13219 (ResolveInfo)nextReceiver;
13220
13221 boolean skip = false;
13222 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013223 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
13224 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013225 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013226 if (!info.activityInfo.exported) {
13227 Slog.w(TAG, "Permission Denial: broadcasting "
13228 + r.intent.toString()
13229 + " from " + r.callerPackage + " (pid=" + r.callingPid
13230 + ", uid=" + r.callingUid + ")"
13231 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
13232 + " due to receiver " + info.activityInfo.packageName
13233 + "/" + info.activityInfo.name);
13234 } else {
13235 Slog.w(TAG, "Permission Denial: broadcasting "
13236 + r.intent.toString()
13237 + " from " + r.callerPackage + " (pid=" + r.callingPid
13238 + ", uid=" + r.callingUid + ")"
13239 + " requires " + info.activityInfo.permission
13240 + " due to receiver " + info.activityInfo.packageName
13241 + "/" + info.activityInfo.name);
13242 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013243 skip = true;
13244 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070013245 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013246 r.requiredPermission != null) {
13247 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013248 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013249 checkPermission(r.requiredPermission,
13250 info.activityInfo.applicationInfo.packageName);
13251 } catch (RemoteException e) {
13252 perm = PackageManager.PERMISSION_DENIED;
13253 }
13254 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013255 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013256 + r.intent + " to "
13257 + info.activityInfo.applicationInfo.packageName
13258 + " requires " + r.requiredPermission
13259 + " due to sender " + r.callerPackage
13260 + " (uid " + r.callingUid + ")");
13261 skip = true;
13262 }
13263 }
13264 if (r.curApp != null && r.curApp.crashing) {
13265 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013266 if (DEBUG_BROADCAST) Slog.v(TAG,
13267 "Skipping deliver ordered " + r + " to " + r.curApp
13268 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013269 skip = true;
13270 }
13271
13272 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013273 if (DEBUG_BROADCAST) Slog.v(TAG,
13274 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013275 r.receiver = null;
13276 r.curFilter = null;
13277 r.state = BroadcastRecord.IDLE;
13278 scheduleBroadcastsLocked();
13279 return;
13280 }
13281
13282 r.state = BroadcastRecord.APP_RECEIVE;
13283 String targetProcess = info.activityInfo.processName;
13284 r.curComponent = new ComponentName(
13285 info.activityInfo.applicationInfo.packageName,
13286 info.activityInfo.name);
13287 r.curReceiver = info.activityInfo;
13288
Dianne Hackborne7f97212011-02-24 14:40:20 -080013289 // Broadcast is being executed, its package can't be stopped.
13290 try {
13291 AppGlobals.getPackageManager().setPackageStoppedState(
13292 r.curComponent.getPackageName(), false);
13293 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080013294 } catch (IllegalArgumentException e) {
13295 Slog.w(TAG, "Failed trying to unstop package "
13296 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080013297 }
13298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013299 // Is this receiver's application already running?
13300 ProcessRecord app = getProcessRecordLocked(targetProcess,
13301 info.activityInfo.applicationInfo.uid);
13302 if (app != null && app.thread != null) {
13303 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070013304 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013305 processCurBroadcastLocked(r, app);
13306 return;
13307 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013308 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013309 + r.curComponent, e);
13310 }
13311
13312 // If a dead object exception was thrown -- fall through to
13313 // restart the application.
13314 }
13315
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013316 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013317 if (DEBUG_BROADCAST) Slog.v(TAG,
13318 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013319 if ((r.curApp=startProcessLocked(targetProcess,
13320 info.activityInfo.applicationInfo, true,
13321 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013322 "broadcast", r.curComponent,
13323 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
13324 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013325 // Ah, this recipient is unavailable. Finish it if necessary,
13326 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013327 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013328 + info.activityInfo.applicationInfo.packageName + "/"
13329 + info.activityInfo.applicationInfo.uid + " for broadcast "
13330 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070013331 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013332 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
13333 r.resultExtras, r.resultAbort, true);
13334 scheduleBroadcastsLocked();
13335 r.state = BroadcastRecord.IDLE;
13336 return;
13337 }
13338
13339 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013340 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013341 }
13342 }
13343
13344 // =========================================================
13345 // INSTRUMENTATION
13346 // =========================================================
13347
13348 public boolean startInstrumentation(ComponentName className,
13349 String profileFile, int flags, Bundle arguments,
13350 IInstrumentationWatcher watcher) {
13351 // Refuse possible leaked file descriptors
13352 if (arguments != null && arguments.hasFileDescriptors()) {
13353 throw new IllegalArgumentException("File descriptors passed in Bundle");
13354 }
13355
13356 synchronized(this) {
13357 InstrumentationInfo ii = null;
13358 ApplicationInfo ai = null;
13359 try {
13360 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013361 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013362 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013363 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013364 } catch (PackageManager.NameNotFoundException e) {
13365 }
13366 if (ii == null) {
13367 reportStartInstrumentationFailure(watcher, className,
13368 "Unable to find instrumentation info for: " + className);
13369 return false;
13370 }
13371 if (ai == null) {
13372 reportStartInstrumentationFailure(watcher, className,
13373 "Unable to find instrumentation target package: " + ii.targetPackage);
13374 return false;
13375 }
13376
13377 int match = mContext.getPackageManager().checkSignatures(
13378 ii.targetPackage, ii.packageName);
13379 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13380 String msg = "Permission Denial: starting instrumentation "
13381 + className + " from pid="
13382 + Binder.getCallingPid()
13383 + ", uid=" + Binder.getCallingPid()
13384 + " not allowed because package " + ii.packageName
13385 + " does not have a signature matching the target "
13386 + ii.targetPackage;
13387 reportStartInstrumentationFailure(watcher, className, msg);
13388 throw new SecurityException(msg);
13389 }
13390
13391 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070013392 // Instrumentation can kill and relaunch even persistent processes
13393 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013394 ProcessRecord app = addAppLocked(ai);
13395 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013396 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013397 app.instrumentationProfileFile = profileFile;
13398 app.instrumentationArguments = arguments;
13399 app.instrumentationWatcher = watcher;
13400 app.instrumentationResultClass = className;
13401 Binder.restoreCallingIdentity(origId);
13402 }
13403
13404 return true;
13405 }
13406
13407 /**
13408 * Report errors that occur while attempting to start Instrumentation. Always writes the
13409 * error to the logs, but if somebody is watching, send the report there too. This enables
13410 * the "am" command to report errors with more information.
13411 *
13412 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
13413 * @param cn The component name of the instrumentation.
13414 * @param report The error report.
13415 */
13416 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13417 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013418 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013419 try {
13420 if (watcher != null) {
13421 Bundle results = new Bundle();
13422 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13423 results.putString("Error", report);
13424 watcher.instrumentationStatus(cn, -1, results);
13425 }
13426 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013427 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013428 }
13429 }
13430
13431 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13432 if (app.instrumentationWatcher != null) {
13433 try {
13434 // NOTE: IInstrumentationWatcher *must* be oneway here
13435 app.instrumentationWatcher.instrumentationFinished(
13436 app.instrumentationClass,
13437 resultCode,
13438 results);
13439 } catch (RemoteException e) {
13440 }
13441 }
13442 app.instrumentationWatcher = null;
13443 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013444 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013445 app.instrumentationProfileFile = null;
13446 app.instrumentationArguments = null;
13447
Christopher Tate3dacd842011-08-19 14:56:15 -070013448 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013449 }
13450
13451 public void finishInstrumentation(IApplicationThread target,
13452 int resultCode, Bundle results) {
13453 // Refuse possible leaked file descriptors
13454 if (results != null && results.hasFileDescriptors()) {
13455 throw new IllegalArgumentException("File descriptors passed in Intent");
13456 }
13457
13458 synchronized(this) {
13459 ProcessRecord app = getRecordForAppLocked(target);
13460 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013461 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013462 return;
13463 }
13464 final long origId = Binder.clearCallingIdentity();
13465 finishInstrumentationLocked(app, resultCode, results);
13466 Binder.restoreCallingIdentity(origId);
13467 }
13468 }
13469
13470 // =========================================================
13471 // CONFIGURATION
13472 // =========================================================
13473
13474 public ConfigurationInfo getDeviceConfigurationInfo() {
13475 ConfigurationInfo config = new ConfigurationInfo();
13476 synchronized (this) {
13477 config.reqTouchScreen = mConfiguration.touchscreen;
13478 config.reqKeyboardType = mConfiguration.keyboard;
13479 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013480 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13481 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013482 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13483 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013484 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13485 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013486 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13487 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070013488 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013489 }
13490 return config;
13491 }
13492
13493 public Configuration getConfiguration() {
13494 Configuration ci;
13495 synchronized(this) {
13496 ci = new Configuration(mConfiguration);
13497 }
13498 return ci;
13499 }
13500
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013501 public void updatePersistentConfiguration(Configuration values) {
13502 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13503 "updateConfiguration()");
13504 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13505 "updateConfiguration()");
13506 if (values == null) {
13507 throw new NullPointerException("Configuration must not be null");
13508 }
13509
13510 synchronized(this) {
13511 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013512 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013513 Binder.restoreCallingIdentity(origId);
13514 }
13515 }
13516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013517 public void updateConfiguration(Configuration values) {
13518 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13519 "updateConfiguration()");
13520
13521 synchronized(this) {
13522 if (values == null && mWindowManager != null) {
13523 // sentinel: fetch the current configuration from the window manager
13524 values = mWindowManager.computeNewConfiguration();
13525 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013526
13527 if (mWindowManager != null) {
13528 mProcessList.applyDisplaySize(mWindowManager);
13529 }
13530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013531 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013532 if (values != null) {
13533 Settings.System.clearConfiguration(values);
13534 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013535 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013536 Binder.restoreCallingIdentity(origId);
13537 }
13538 }
13539
13540 /**
13541 * Do either or both things: (1) change the current configuration, and (2)
13542 * make sure the given activity is running with the (now) current
13543 * configuration. Returns true if the activity has been left running, or
13544 * false if <var>starting</var> is being destroyed to match the new
13545 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013546 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013547 */
13548 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013549 ActivityRecord starting, boolean persistent, boolean initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013550 int changes = 0;
13551
13552 boolean kept = true;
13553
13554 if (values != null) {
13555 Configuration newConfig = new Configuration(mConfiguration);
13556 changes = newConfig.updateFrom(values);
13557 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013558 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013559 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013560 }
13561
Doug Zongker2bec3d42009-12-04 12:52:44 -080013562 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013563
Dianne Hackborn813075a62011-11-14 17:45:19 -080013564 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013565 saveLocaleLocked(values.locale,
13566 !values.locale.equals(mConfiguration.locale),
13567 values.userSetLocale);
13568 }
13569
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013570 mConfigurationSeq++;
13571 if (mConfigurationSeq <= 0) {
13572 mConfigurationSeq = 1;
13573 }
13574 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013575 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013576 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013577
13578 final Configuration configCopy = new Configuration(mConfiguration);
13579
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013580 AttributeCache ac = AttributeCache.instance();
13581 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013582 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013583 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013584
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013585 // Make sure all resources in our process are updated
13586 // right now, so that anyone who is going to retrieve
13587 // resource values after we return will be sure to get
13588 // the new ones. This is especially important during
13589 // boot, where the first config change needs to guarantee
13590 // all resources have that config before following boot
13591 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080013592 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013593
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013594 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013595 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013596 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013597 mHandler.sendMessage(msg);
13598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013599
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013600 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13601 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013602 try {
13603 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013604 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013605 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013606 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013607 }
13608 } catch (Exception e) {
13609 }
13610 }
13611 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013612 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13613 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013614 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13615 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013616 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13617 broadcastIntentLocked(null, null,
13618 new Intent(Intent.ACTION_LOCALE_CHANGED),
13619 null, null, 0, null, null,
13620 null, false, false, MY_PID, Process.SYSTEM_UID);
13621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013622 }
13623 }
13624
13625 if (changes != 0 && starting == null) {
13626 // If the configuration changed, and the caller is not already
13627 // in the process of starting an activity, then find the top
13628 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013629 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013630 }
13631
13632 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013633 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013634 // And we need to make sure at this point that all other activities
13635 // are made visible with the correct configuration.
13636 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013637 }
13638
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013639 if (values != null && mWindowManager != null) {
13640 mWindowManager.setNewConfiguration(mConfiguration);
13641 }
13642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013643 return kept;
13644 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013645
13646 /**
13647 * Save the locale. You must be inside a synchronized (this) block.
13648 */
13649 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13650 if(isDiff) {
13651 SystemProperties.set("user.language", l.getLanguage());
13652 SystemProperties.set("user.region", l.getCountry());
13653 }
13654
13655 if(isPersist) {
13656 SystemProperties.set("persist.sys.language", l.getLanguage());
13657 SystemProperties.set("persist.sys.country", l.getCountry());
13658 SystemProperties.set("persist.sys.localevar", l.getVariant());
13659 }
13660 }
13661
13662 // =========================================================
13663 // LIFETIME MANAGEMENT
13664 // =========================================================
13665
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013666 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013667 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013668 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013669 // This adjustment has already been computed. If we are calling
13670 // from the top, we may have already computed our adjustment with
13671 // an earlier hidden adjustment that isn't really for us... if
13672 // so, use the new hidden adjustment.
13673 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013674 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013675 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013676 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013677 }
13678
13679 if (app.thread == null) {
13680 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013681 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013682 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013683 }
13684
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013685 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13686 app.adjSource = null;
13687 app.adjTarget = null;
13688 app.empty = false;
13689 app.hidden = false;
13690
13691 final int activitiesSize = app.activities.size();
13692
Dianne Hackborn7d608422011-08-07 16:24:18 -070013693 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013694 // The max adjustment doesn't allow this app to be anything
13695 // below foreground, so it is not worth doing work for it.
13696 app.adjType = "fixed";
13697 app.adjSeq = mAdjSeq;
13698 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013699 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013700 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013701 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013702 // System process can do UI, and when they do we want to have
13703 // them trim their memory after the user leaves the UI. To
13704 // facilitate this, here we need to determine whether or not it
13705 // is currently showing UI.
13706 app.systemNoUi = true;
13707 if (app == TOP_APP) {
13708 app.systemNoUi = false;
13709 } else if (activitiesSize > 0) {
13710 for (int j = 0; j < activitiesSize; j++) {
13711 final ActivityRecord r = app.activities.get(j);
13712 if (r.visible) {
13713 app.systemNoUi = false;
13714 break;
13715 }
13716 }
13717 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013718 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013719 }
13720
13721 final boolean hadForegroundActivities = app.foregroundActivities;
13722
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013723 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013724 app.keeping = false;
13725 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013726
The Android Open Source Project4df24232009-03-05 14:34:35 -080013727 // Determine the importance of the process, starting with most
13728 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013729 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013730 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013731 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013732 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013733 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013734 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013735 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013736 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013737 } else if (app.instrumentationClass != null) {
13738 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013739 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013740 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013741 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013742 } else if (app.curReceiver != null ||
13743 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13744 // An app that is currently receiving a broadcast also
13745 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013746 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013747 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013748 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013749 } else if (app.executingServices.size() > 0) {
13750 // An app that is currently executing a service callback also
13751 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013752 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013753 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013754 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013755 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013756 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013757 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013758 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013759 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013760 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013761 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013762 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013763 // A very not-needed process. If this is lower in the lru list,
13764 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013765 adj = hiddenAdj;
13766 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013767 app.hidden = true;
13768 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013769 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013770 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013771
13772 // Examine all activities if not already foreground.
13773 if (!app.foregroundActivities && activitiesSize > 0) {
13774 for (int j = 0; j < activitiesSize; j++) {
13775 final ActivityRecord r = app.activities.get(j);
13776 if (r.visible) {
13777 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013778 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13779 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013780 app.adjType = "visible";
13781 }
13782 schedGroup = Process.THREAD_GROUP_DEFAULT;
13783 app.hidden = false;
13784 app.foregroundActivities = true;
13785 break;
13786 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13787 || r.state == ActivityState.STOPPING) {
13788 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013789 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13790 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013791 app.adjType = "stopping";
13792 }
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -080013793 app.hidden = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013794 app.foregroundActivities = true;
13795 }
13796 }
13797 }
13798
Dianne Hackborn7d608422011-08-07 16:24:18 -070013799 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013800 if (app.foregroundServices) {
13801 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013802 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013803 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013804 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013805 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013806 } else if (app.forcingToForeground != null) {
13807 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013808 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013809 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013810 app.adjType = "force-foreground";
13811 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013812 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013813 }
13814 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013815
Dianne Hackborn7d608422011-08-07 16:24:18 -070013816 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013817 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013818 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013819 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013820 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013821 app.adjType = "heavy";
13822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013823
Dianne Hackborn7d608422011-08-07 16:24:18 -070013824 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013825 // This process is hosting what we currently consider to be the
13826 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013827 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013828 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013829 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013830 app.adjType = "home";
13831 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013832
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013833 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13834 && app.activities.size() > 0) {
13835 // This was the previous process that showed UI to the user.
13836 // We want to try to keep it around more aggressively, to give
13837 // a good experience around switching between two apps.
13838 adj = ProcessList.PREVIOUS_APP_ADJ;
13839 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13840 app.hidden = false;
13841 app.adjType = "previous";
13842 }
13843
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013844 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13845 + " reason=" + app.adjType);
13846
The Android Open Source Project4df24232009-03-05 14:34:35 -080013847 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013848 // there are applications dependent on our services or providers, but
13849 // this gives us a baseline and makes sure we don't get into an
13850 // infinite recursion.
13851 app.adjSeq = mAdjSeq;
13852 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013853
Christopher Tate6fa95972009-06-05 18:43:55 -070013854 if (mBackupTarget != null && app == mBackupTarget.app) {
13855 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013856 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013857 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013858 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013859 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013860 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013861 }
13862 }
13863
Dianne Hackborn7d608422011-08-07 16:24:18 -070013864 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013865 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013866 final long now = SystemClock.uptimeMillis();
13867 // This process is more important if the top activity is
13868 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013869 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013870 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013871 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013872 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013873 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013874 // If this process has shown some UI, let it immediately
13875 // go to the LRU list because it may be pretty heavy with
13876 // UI stuff. We'll tag it with a label just to help
13877 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013878 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013879 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013880 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013881 } else {
13882 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13883 // This service has seen some activity within
13884 // recent memory, so we will keep its process ahead
13885 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013886 if (adj > ProcessList.SERVICE_ADJ) {
13887 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013888 app.adjType = "started-services";
13889 app.hidden = false;
13890 }
13891 }
13892 // If we have let the service slide into the background
13893 // state, still have some text describing what it is doing
13894 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013895 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013896 app.adjType = "started-bg-services";
13897 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013898 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013899 // Don't kill this process because it is doing work; it
13900 // has said it is doing work.
13901 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013902 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013903 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013904 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013905 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013906 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013907 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013908 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013909 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013910 // XXX should compute this based on the max of
13911 // all connected clients.
13912 ConnectionRecord cr = clist.get(i);
13913 if (cr.binding.client == app) {
13914 // Binding to ourself is not interesting.
13915 continue;
13916 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013917 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013918 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013919 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013920 int myHiddenAdj = hiddenAdj;
13921 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013922 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013923 myHiddenAdj = client.hiddenAdj;
13924 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013925 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013926 }
13927 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013928 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013929 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013930 String adjType = null;
13931 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13932 // Not doing bind OOM management, so treat
13933 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013934 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013935 // If this process has shown some UI, let it immediately
13936 // go to the LRU list because it may be pretty heavy with
13937 // UI stuff. We'll tag it with a label just to help
13938 // debug and understand what is going on.
13939 if (adj > clientAdj) {
13940 adjType = "bound-bg-ui-services";
13941 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013942 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013943 clientAdj = adj;
13944 } else {
13945 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13946 // This service has not seen activity within
13947 // recent memory, so allow it to drop to the
13948 // LRU list if there is no other reason to keep
13949 // it around. We'll also tag it with a label just
13950 // to help debug and undertand what is going on.
13951 if (adj > clientAdj) {
13952 adjType = "bound-bg-services";
13953 }
13954 clientAdj = adj;
13955 }
13956 }
13957 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013958 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013959 // If this process has recently shown UI, and
13960 // the process that is binding to it is less
13961 // important than being visible, then we don't
13962 // care about the binding as much as we care
13963 // about letting this process get into the LRU
13964 // list to be killed and restarted if needed for
13965 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013966 if (app.hasShownUi && app != mHomeProcess
13967 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013968 adjType = "bound-bg-ui-services";
13969 } else {
13970 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13971 |Context.BIND_IMPORTANT)) != 0) {
13972 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013973 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13974 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13975 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13976 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13977 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013978 adj = clientAdj;
13979 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013980 app.pendingUiClean = true;
13981 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13982 adj = ProcessList.VISIBLE_APP_ADJ;
13983 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013984 }
13985 if (!client.hidden) {
13986 app.hidden = false;
13987 }
13988 if (client.keeping) {
13989 app.keeping = true;
13990 }
13991 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013992 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013993 }
13994 if (adjType != null) {
13995 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013996 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13997 .REASON_SERVICE_IN_USE;
13998 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013999 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014000 app.adjTarget = s.name;
14001 }
14002 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14003 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14004 schedGroup = Process.THREAD_GROUP_DEFAULT;
14005 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014006 }
14007 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014008 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14009 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014010 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014011 (a.visible || a.state == ActivityState.RESUMED
14012 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014013 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014014 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14015 schedGroup = Process.THREAD_GROUP_DEFAULT;
14016 }
14017 app.hidden = false;
14018 app.adjType = "service";
14019 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14020 .REASON_SERVICE_IN_USE;
14021 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014022 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014023 app.adjTarget = s.name;
14024 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014026 }
14027 }
14028 }
14029 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014030
Dianne Hackborn287952c2010-09-22 22:34:31 -070014031 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014032 // would like to avoid killing it unless it would prevent the current
14033 // application from running. By default we put the process in
14034 // with the rest of the background processes; as we scan through
14035 // its services we may bump it up from there.
14036 if (adj > hiddenAdj) {
14037 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014038 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014039 app.adjType = "bg-services";
14040 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014041 }
14042
Dianne Hackborn7d608422011-08-07 16:24:18 -070014043 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014044 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014045 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014046 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014047 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014048 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014049 if (cpr.clients.size() != 0) {
14050 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014051 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014052 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070014053 if (client == app) {
14054 // Being our own client is not interesting.
14055 continue;
14056 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014057 int myHiddenAdj = hiddenAdj;
14058 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014059 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014060 myHiddenAdj = client.hiddenAdj;
14061 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014062 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014063 }
14064 }
14065 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014066 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014067 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014068 if (app.hasShownUi && app != mHomeProcess
14069 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014070 app.adjType = "bg-ui-provider";
14071 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014072 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14073 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014074 app.adjType = "provider";
14075 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014076 if (!client.hidden) {
14077 app.hidden = false;
14078 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014079 if (client.keeping) {
14080 app.keeping = true;
14081 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070014082 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14083 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014084 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014085 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014086 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014087 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014088 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14089 schedGroup = Process.THREAD_GROUP_DEFAULT;
14090 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014091 }
14092 }
14093 // If the provider has external (non-framework) process
14094 // dependencies, ensure that its adjustment is at least
14095 // FOREGROUND_APP_ADJ.
14096 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014097 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14098 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014099 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014100 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014101 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014102 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014103 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014104 }
14105 }
14106 }
14107 }
14108
14109 app.curRawAdj = adj;
14110
Joe Onorato8a9b2202010-02-26 18:56:32 -080014111 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014112 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14113 if (adj > app.maxAdj) {
14114 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014115 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014116 schedGroup = Process.THREAD_GROUP_DEFAULT;
14117 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014118 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014119 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014120 app.keeping = true;
14121 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014122
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014123 if (app.hasAboveClient) {
14124 // If this process has bound to any services with BIND_ABOVE_CLIENT,
14125 // then we need to drop its adjustment to be lower than the service's
14126 // in order to honor the request. We want to drop it by one adjustment
14127 // level... but there is special meaning applied to various levels so
14128 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014129 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014130 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070014131 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14132 adj = ProcessList.VISIBLE_APP_ADJ;
14133 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14134 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14135 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14136 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014137 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014138 adj++;
14139 }
14140 }
14141
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014142 if (adj == ProcessList.SERVICE_ADJ) {
14143 if (doingAll) {
14144 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14145 mNewNumServiceProcs++;
14146 }
14147 if (app.serviceb) {
14148 adj = ProcessList.SERVICE_B_ADJ;
14149 }
14150 } else {
14151 app.serviceb = false;
14152 }
14153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014154 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014155 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014156
14157 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070014158 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
14159 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014160 }
14161
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014162 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014163 }
14164
14165 /**
14166 * Ask a given process to GC right now.
14167 */
14168 final void performAppGcLocked(ProcessRecord app) {
14169 try {
14170 app.lastRequestedGc = SystemClock.uptimeMillis();
14171 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014172 if (app.reportLowMemory) {
14173 app.reportLowMemory = false;
14174 app.thread.scheduleLowMemory();
14175 } else {
14176 app.thread.processInBackground();
14177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014178 }
14179 } catch (Exception e) {
14180 // whatever.
14181 }
14182 }
14183
14184 /**
14185 * Returns true if things are idle enough to perform GCs.
14186 */
Josh Bartel7f208742010-02-25 11:01:44 -060014187 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014188 return mParallelBroadcasts.size() == 0
14189 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014190 && (mSleeping || (mMainStack.mResumedActivity != null &&
14191 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014192 }
14193
14194 /**
14195 * Perform GCs on all processes that are waiting for it, but only
14196 * if things are idle.
14197 */
14198 final void performAppGcsLocked() {
14199 final int N = mProcessesToGc.size();
14200 if (N <= 0) {
14201 return;
14202 }
Josh Bartel7f208742010-02-25 11:01:44 -060014203 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014204 while (mProcessesToGc.size() > 0) {
14205 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014206 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014207 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14208 <= SystemClock.uptimeMillis()) {
14209 // To avoid spamming the system, we will GC processes one
14210 // at a time, waiting a few seconds between each.
14211 performAppGcLocked(proc);
14212 scheduleAppGcsLocked();
14213 return;
14214 } else {
14215 // It hasn't been long enough since we last GCed this
14216 // process... put it in the list to wait for its time.
14217 addProcessToGcListLocked(proc);
14218 break;
14219 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014220 }
14221 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014222
14223 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014224 }
14225 }
14226
14227 /**
14228 * If all looks good, perform GCs on all processes waiting for them.
14229 */
14230 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060014231 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014232 performAppGcsLocked();
14233 return;
14234 }
14235 // Still not idle, wait some more.
14236 scheduleAppGcsLocked();
14237 }
14238
14239 /**
14240 * Schedule the execution of all pending app GCs.
14241 */
14242 final void scheduleAppGcsLocked() {
14243 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014244
14245 if (mProcessesToGc.size() > 0) {
14246 // Schedule a GC for the time to the next process.
14247 ProcessRecord proc = mProcessesToGc.get(0);
14248 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14249
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014250 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014251 long now = SystemClock.uptimeMillis();
14252 if (when < (now+GC_TIMEOUT)) {
14253 when = now + GC_TIMEOUT;
14254 }
14255 mHandler.sendMessageAtTime(msg, when);
14256 }
14257 }
14258
14259 /**
14260 * Add a process to the array of processes waiting to be GCed. Keeps the
14261 * list in sorted order by the last GC time. The process can't already be
14262 * on the list.
14263 */
14264 final void addProcessToGcListLocked(ProcessRecord proc) {
14265 boolean added = false;
14266 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14267 if (mProcessesToGc.get(i).lastRequestedGc <
14268 proc.lastRequestedGc) {
14269 added = true;
14270 mProcessesToGc.add(i+1, proc);
14271 break;
14272 }
14273 }
14274 if (!added) {
14275 mProcessesToGc.add(0, proc);
14276 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014277 }
14278
14279 /**
14280 * Set up to ask a process to GC itself. This will either do it
14281 * immediately, or put it on the list of processes to gc the next
14282 * time things are idle.
14283 */
14284 final void scheduleAppGcLocked(ProcessRecord app) {
14285 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014286 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014287 return;
14288 }
14289 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014290 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014291 scheduleAppGcsLocked();
14292 }
14293 }
14294
Dianne Hackborn287952c2010-09-22 22:34:31 -070014295 final void checkExcessivePowerUsageLocked(boolean doKills) {
14296 updateCpuStatsNow();
14297
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014298 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014299 boolean doWakeKills = doKills;
14300 boolean doCpuKills = doKills;
14301 if (mLastPowerCheckRealtime == 0) {
14302 doWakeKills = false;
14303 }
14304 if (mLastPowerCheckUptime == 0) {
14305 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014306 }
14307 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014308 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014309 }
14310 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014311 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14312 final long curUptime = SystemClock.uptimeMillis();
14313 final long uptimeSince = curUptime - mLastPowerCheckUptime;
14314 mLastPowerCheckRealtime = curRealtime;
14315 mLastPowerCheckUptime = curUptime;
14316 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14317 doWakeKills = false;
14318 }
14319 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14320 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014321 }
14322 int i = mLruProcesses.size();
14323 while (i > 0) {
14324 i--;
14325 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014326 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014327 long wtime;
14328 synchronized (stats) {
14329 wtime = stats.getProcessWakeTime(app.info.uid,
14330 app.pid, curRealtime);
14331 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014332 long wtimeUsed = wtime - app.lastWakeTime;
14333 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14334 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014335 StringBuilder sb = new StringBuilder(128);
14336 sb.append("Wake for ");
14337 app.toShortString(sb);
14338 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014339 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014340 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014341 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014342 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014343 sb.append((wtimeUsed*100)/realtimeSince);
14344 sb.append("%)");
14345 Slog.i(TAG, sb.toString());
14346 sb.setLength(0);
14347 sb.append("CPU for ");
14348 app.toShortString(sb);
14349 sb.append(": over ");
14350 TimeUtils.formatDuration(uptimeSince, sb);
14351 sb.append(" used ");
14352 TimeUtils.formatDuration(cputimeUsed, sb);
14353 sb.append(" (");
14354 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014355 sb.append("%)");
14356 Slog.i(TAG, sb.toString());
14357 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014358 // If a process has held a wake lock for more
14359 // than 50% of the time during this period,
14360 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070014361 if (doWakeKills && realtimeSince > 0
14362 && ((wtimeUsed*100)/realtimeSince) >= 50) {
14363 synchronized (stats) {
14364 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14365 realtimeSince, wtimeUsed);
14366 }
14367 Slog.w(TAG, "Excessive wake lock in " + app.processName
14368 + " (pid " + app.pid + "): held " + wtimeUsed
14369 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014370 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14371 app.processName, app.setAdj, "excessive wake lock");
14372 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014373 } else if (doCpuKills && uptimeSince > 0
14374 && ((cputimeUsed*100)/uptimeSince) >= 50) {
14375 synchronized (stats) {
14376 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14377 uptimeSince, cputimeUsed);
14378 }
14379 Slog.w(TAG, "Excessive CPU in " + app.processName
14380 + " (pid " + app.pid + "): used " + cputimeUsed
14381 + " during " + uptimeSince);
14382 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14383 app.processName, app.setAdj, "excessive cpu");
14384 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014385 } else {
14386 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014387 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014388 }
14389 }
14390 }
14391 }
14392
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014393 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014394 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014395 app.hiddenAdj = hiddenAdj;
14396
14397 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014398 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014399 }
14400
Dianne Hackborn287952c2010-09-22 22:34:31 -070014401 final boolean wasKeeping = app.keeping;
14402
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014403 boolean success = true;
14404
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014405 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014406
Jeff Brown10e89712011-07-08 18:52:57 -070014407 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070014408 if (false) {
14409 // Removing for now. Forcing GCs is not so useful anymore
14410 // with Dalvik, and the new memory level hint facility is
14411 // better for what we need to do these days.
14412 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
14413 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14414 // If this app is transitioning from foreground to
14415 // non-foreground, have it do a gc.
14416 scheduleAppGcLocked(app);
14417 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14418 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14419 // Likewise do a gc when an app is moving in to the
14420 // background (such as a service stopping).
14421 scheduleAppGcLocked(app);
14422 }
Jeff Brown10e89712011-07-08 18:52:57 -070014423 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014424
Jeff Brown10e89712011-07-08 18:52:57 -070014425 if (wasKeeping && !app.keeping) {
14426 // This app is no longer something we want to keep. Note
14427 // its current wake lock time to later know to kill it if
14428 // it is not behaving well.
14429 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14430 synchronized (stats) {
14431 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14432 app.pid, SystemClock.elapsedRealtime());
14433 }
14434 app.lastCpuTime = app.curCpuTime;
14435 }
14436
14437 app.setRawAdj = app.curRawAdj;
14438 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014439
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014440 if (app.curAdj != app.setAdj) {
14441 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackbornbbb09ac2011-11-30 11:31:29 -080014442 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014443 TAG, "Set " + app.pid + " " + app.processName +
14444 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014445 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070014446 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014447 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014448 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070014449 }
14450 }
14451 if (app.setSchedGroup != app.curSchedGroup) {
14452 app.setSchedGroup = app.curSchedGroup;
14453 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14454 "Setting process group of " + app.processName
14455 + " to " + app.curSchedGroup);
14456 if (app.waitingToKill != null &&
14457 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14458 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14459 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14460 app.processName, app.setAdj, app.waitingToKill);
14461 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014462 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070014463 } else {
14464 if (true) {
14465 long oldId = Binder.clearCallingIdentity();
14466 try {
14467 Process.setProcessGroup(app.pid, app.curSchedGroup);
14468 } catch (Exception e) {
14469 Slog.w(TAG, "Failed setting process group of " + app.pid
14470 + " to " + app.curSchedGroup);
14471 e.printStackTrace();
14472 } finally {
14473 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014474 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014475 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070014476 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014477 try {
Jeff Brown10e89712011-07-08 18:52:57 -070014478 app.thread.setSchedulingGroup(app.curSchedGroup);
14479 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014480 }
14481 }
14482 }
14483 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014484 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014485 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014486 }
14487
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014488 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014489 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014490 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014491 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014492 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014493 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014494 }
14495 }
14496 return resumedActivity;
14497 }
14498
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014499 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014500 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014501 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14502 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014503 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14504 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014505
14506 mAdjSeq++;
14507
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014508 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014509 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14510 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014511 if (nowHidden != wasHidden) {
14512 // Changed to/from hidden state, so apps after it in the LRU
14513 // list may also be changed.
14514 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014515 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014516 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014517 }
14518
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014519 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014520 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014521 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14522
14523 if (false) {
14524 RuntimeException e = new RuntimeException();
14525 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014526 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014527 }
14528
14529 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014530 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014531
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014532 // Let's determine how many processes we have running vs.
14533 // how many slots we have for background processes; we may want
14534 // to put multiple processes in a slot of there are enough of
14535 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014536 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014537 int factor = (mLruProcesses.size()-4)/numSlots;
14538 if (factor < 1) factor = 1;
14539 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014540 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014541
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014542 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014543 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014544 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014545 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014546 while (i > 0) {
14547 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014548 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080014549 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014550 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14551 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014552 && app.curAdj == curHiddenAdj) {
14553 step++;
14554 if (step >= factor) {
14555 step = 0;
14556 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014557 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014558 }
14559 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014560 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014561 numHidden++;
14562 if (numHidden > mProcessLimit) {
14563 Slog.i(TAG, "No longer want " + app.processName
14564 + " (pid " + app.pid + "): hidden #" + numHidden);
14565 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14566 app.processName, app.setAdj, "too many background");
14567 app.killedBackground = true;
14568 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070014569 }
14570 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014571 }
14572 }
14573
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014574 mNumServiceProcs = mNewNumServiceProcs;
14575
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014576 // Now determine the memory trimming level of background processes.
14577 // Unfortunately we need to start at the back of the list to do this
14578 // properly. We only do this if the number of background apps we
14579 // are managing to keep around is less than half the maximum we desire;
14580 // if we are keeping a good number around, we'll let them use whatever
14581 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014582 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014583 final int N = mLruProcesses.size();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014584 factor = numHidden/3;
14585 int minFactor = 2;
14586 if (mHomeProcess != null) minFactor++;
14587 if (mPreviousProcess != null) minFactor++;
14588 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014589 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014590 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014591 for (i=0; i<N; i++) {
14592 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014593 if (app.curAdj >= ProcessList.HOME_APP_ADJ
14594 && app.curAdj != ProcessList.SERVICE_B_ADJ
14595 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014596 if (app.trimMemoryLevel < curLevel && app.thread != null) {
14597 try {
14598 app.thread.scheduleTrimMemory(curLevel);
14599 } catch (RemoteException e) {
14600 }
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080014601 if (false) {
14602 // For now we won't do this; our memory trimming seems
14603 // to be good enough at this point that destroying
14604 // activities causes more harm than good.
14605 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14606 && app != mHomeProcess && app != mPreviousProcess) {
14607 // For these apps we will also finish their activities
14608 // to help them free memory.
14609 mMainStack.destroyActivitiesLocked(app, false, "trim");
14610 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014611 }
14612 }
14613 app.trimMemoryLevel = curLevel;
14614 step++;
14615 if (step >= factor) {
14616 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014617 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14618 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014619 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014620 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14621 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014622 break;
14623 }
14624 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014625 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014626 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014627 && app.thread != null) {
14628 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014629 app.thread.scheduleTrimMemory(
14630 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014631 } catch (RemoteException e) {
14632 }
14633 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014634 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014635 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014636 && app.pendingUiClean) {
14637 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14638 && app.thread != null) {
14639 try {
14640 app.thread.scheduleTrimMemory(
14641 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14642 } catch (RemoteException e) {
14643 }
14644 }
14645 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14646 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014647 } else {
14648 app.trimMemoryLevel = 0;
14649 }
14650 }
14651 } else {
14652 final int N = mLruProcesses.size();
14653 for (i=0; i<N; i++) {
14654 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014655 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014656 && app.pendingUiClean) {
14657 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14658 && app.thread != null) {
14659 try {
14660 app.thread.scheduleTrimMemory(
14661 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14662 } catch (RemoteException e) {
14663 }
14664 }
14665 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14666 app.pendingUiClean = false;
14667 } else {
14668 app.trimMemoryLevel = 0;
14669 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014670 }
14671 }
14672
14673 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070014674 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014676 }
14677
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014678 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014679 synchronized (this) {
14680 int i;
14681
14682 // First remove any unused application processes whose package
14683 // has been removed.
14684 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14685 final ProcessRecord app = mRemovedProcesses.get(i);
14686 if (app.activities.size() == 0
14687 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014688 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014689 TAG, "Exiting empty application process "
14690 + app.processName + " ("
14691 + (app.thread != null ? app.thread.asBinder() : null)
14692 + ")\n");
14693 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070014694 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14695 app.processName, app.setAdj, "empty");
14696 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014697 } else {
14698 try {
14699 app.thread.scheduleExit();
14700 } catch (Exception e) {
14701 // Ignore exceptions.
14702 }
14703 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014704 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014705 mRemovedProcesses.remove(i);
14706
14707 if (app.persistent) {
14708 if (app.persistent) {
14709 addAppLocked(app.info);
14710 }
14711 }
14712 }
14713 }
14714
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014715 // Now update the oom adj for all processes.
14716 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014717 }
14718 }
14719
14720 /** This method sends the specified signal to each of the persistent apps */
14721 public void signalPersistentProcesses(int sig) throws RemoteException {
14722 if (sig != Process.SIGNAL_USR1) {
14723 throw new SecurityException("Only SIGNAL_USR1 is allowed");
14724 }
14725
14726 synchronized (this) {
14727 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14728 != PackageManager.PERMISSION_GRANTED) {
14729 throw new SecurityException("Requires permission "
14730 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14731 }
14732
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014733 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14734 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014735 if (r.thread != null && r.persistent) {
14736 Process.sendSignal(r.pid, sig);
14737 }
14738 }
14739 }
14740 }
14741
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014742 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14743 if (proc == null || proc == mProfileProc) {
14744 proc = mProfileProc;
14745 path = mProfileFile;
14746 profileType = mProfileType;
14747 clearProfilerLocked();
14748 }
14749 if (proc == null) {
14750 return;
14751 }
14752 try {
14753 proc.thread.profilerControl(false, path, null, profileType);
14754 } catch (RemoteException e) {
14755 throw new IllegalStateException("Process disappeared");
14756 }
14757 }
14758
14759 private void clearProfilerLocked() {
14760 if (mProfileFd != null) {
14761 try {
14762 mProfileFd.close();
14763 } catch (IOException e) {
14764 }
14765 }
14766 mProfileApp = null;
14767 mProfileProc = null;
14768 mProfileFile = null;
14769 mProfileType = 0;
14770 mAutoStopProfiler = false;
14771 }
14772
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014773 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014774 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014775
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014776 try {
14777 synchronized (this) {
14778 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14779 // its own permission.
14780 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14781 != PackageManager.PERMISSION_GRANTED) {
14782 throw new SecurityException("Requires permission "
14783 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014784 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014785
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014786 if (start && fd == null) {
14787 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014788 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014789
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014790 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014791 if (process != null) {
14792 try {
14793 int pid = Integer.parseInt(process);
14794 synchronized (mPidsSelfLocked) {
14795 proc = mPidsSelfLocked.get(pid);
14796 }
14797 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014798 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014799
14800 if (proc == null) {
14801 HashMap<String, SparseArray<ProcessRecord>> all
14802 = mProcessNames.getMap();
14803 SparseArray<ProcessRecord> procs = all.get(process);
14804 if (procs != null && procs.size() > 0) {
14805 proc = procs.valueAt(0);
14806 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014807 }
14808 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014809
14810 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014811 throw new IllegalArgumentException("Unknown process: " + process);
14812 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014813
14814 if (start) {
14815 stopProfilerLocked(null, null, 0);
14816 setProfileApp(proc.info, proc.processName, path, fd, false);
14817 mProfileProc = proc;
14818 mProfileType = profileType;
14819 try {
14820 fd = fd.dup();
14821 } catch (IOException e) {
14822 fd = null;
14823 }
14824 proc.thread.profilerControl(start, path, fd, profileType);
14825 fd = null;
14826 mProfileFd = null;
14827 } else {
14828 stopProfilerLocked(proc, path, profileType);
14829 if (fd != null) {
14830 try {
14831 fd.close();
14832 } catch (IOException e) {
14833 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014834 }
14835 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014836
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014837 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014838 }
14839 } catch (RemoteException e) {
14840 throw new IllegalStateException("Process disappeared");
14841 } finally {
14842 if (fd != null) {
14843 try {
14844 fd.close();
14845 } catch (IOException e) {
14846 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014847 }
14848 }
14849 }
Andy McFadden824c5102010-07-09 16:26:57 -070014850
14851 public boolean dumpHeap(String process, boolean managed,
14852 String path, ParcelFileDescriptor fd) throws RemoteException {
14853
14854 try {
14855 synchronized (this) {
14856 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14857 // its own permission (same as profileControl).
14858 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14859 != PackageManager.PERMISSION_GRANTED) {
14860 throw new SecurityException("Requires permission "
14861 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14862 }
14863
14864 if (fd == null) {
14865 throw new IllegalArgumentException("null fd");
14866 }
14867
14868 ProcessRecord proc = null;
14869 try {
14870 int pid = Integer.parseInt(process);
14871 synchronized (mPidsSelfLocked) {
14872 proc = mPidsSelfLocked.get(pid);
14873 }
14874 } catch (NumberFormatException e) {
14875 }
14876
14877 if (proc == null) {
14878 HashMap<String, SparseArray<ProcessRecord>> all
14879 = mProcessNames.getMap();
14880 SparseArray<ProcessRecord> procs = all.get(process);
14881 if (procs != null && procs.size() > 0) {
14882 proc = procs.valueAt(0);
14883 }
14884 }
14885
14886 if (proc == null || proc.thread == null) {
14887 throw new IllegalArgumentException("Unknown process: " + process);
14888 }
14889
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014890 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14891 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014892 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14893 throw new SecurityException("Process not debuggable: " + proc);
14894 }
14895 }
14896
14897 proc.thread.dumpHeap(managed, path, fd);
14898 fd = null;
14899 return true;
14900 }
14901 } catch (RemoteException e) {
14902 throw new IllegalStateException("Process disappeared");
14903 } finally {
14904 if (fd != null) {
14905 try {
14906 fd.close();
14907 } catch (IOException e) {
14908 }
14909 }
14910 }
14911 }
14912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014913 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14914 public void monitor() {
14915 synchronized (this) { }
14916 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014917
14918 public void onCoreSettingsChange(Bundle settings) {
14919 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14920 ProcessRecord processRecord = mLruProcesses.get(i);
14921 try {
14922 if (processRecord.thread != null) {
14923 processRecord.thread.setCoreSettings(settings);
14924 }
14925 } catch (RemoteException re) {
14926 /* ignore */
14927 }
14928 }
14929 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014930
14931 // Multi-user methods
14932
14933 public boolean switchUser(int userid) {
14934 // TODO
14935 return true;
14936 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014937}