blob: 291ce75333be1deed41ecc09ec6a4faa36cf7c98 [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;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800109import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800110import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.util.PrintWriterPrinter;
112import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700113import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.Gravity;
115import android.view.LayoutInflater;
116import android.view.View;
117import android.view.WindowManager;
118import android.view.WindowManagerPolicy;
119
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700120import java.io.BufferedInputStream;
121import java.io.BufferedOutputStream;
122import java.io.DataInputStream;
123import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import java.io.File;
125import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700126import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200129import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800130import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131import java.io.PrintWriter;
132import java.lang.IllegalStateException;
133import java.lang.ref.WeakReference;
134import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700135import java.util.Collections;
136import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137import java.util.HashMap;
138import java.util.HashSet;
139import java.util.Iterator;
140import java.util.List;
141import java.util.Locale;
142import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700143import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700144import java.util.concurrent.atomic.AtomicBoolean;
145import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700147public final class ActivityManagerService extends ActivityManagerNative
148 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 static final String TAG = "ActivityManager";
150 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400151 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final boolean DEBUG_SWITCH = localLOGV || false;
153 static final boolean DEBUG_TASKS = localLOGV || false;
154 static final boolean DEBUG_PAUSE = localLOGV || false;
155 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
156 static final boolean DEBUG_TRANSITION = localLOGV || false;
157 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700158 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700160 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 static final boolean DEBUG_VISBILITY = localLOGV || false;
162 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700163 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800164 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700166 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700167 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700168 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700169 static final boolean DEBUG_POWER = localLOGV || false;
170 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 static final boolean VALIDATE_TOKENS = false;
172 static final boolean SHOW_ACTIVITY_START_TIME = true;
173
174 // Control over CPU and battery monitoring.
175 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
176 static final boolean MONITOR_CPU_USAGE = true;
177 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
178 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
179 static final boolean MONITOR_THREAD_CPU_USAGE = false;
180
Dianne Hackborn1655be42009-05-08 14:29:01 -0700181 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700182 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700183
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800184 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 // Maximum number of recent tasks that we can remember.
187 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700188
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700189 // Amount of time after a call to stopAppSwitches() during which we will
190 // prevent further untrusted switches from happening.
191 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192
193 // How long we wait for a launched process to attach to the activity manager
194 // before we decide it's never going to come up for real.
195 static final int PROC_START_TIMEOUT = 10*1000;
196
Jeff Brown3f9dd282011-07-08 20:02:19 -0700197 // How long we wait for a launched process to attach to the activity manager
198 // before we decide it's never going to come up for real, when the process was
199 // started with a wrapper for instrumentation (such as Valgrind) because it
200 // could take much longer than usual.
201 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 // How long to wait after going idle before forcing apps to GC.
204 static final int GC_TIMEOUT = 5*1000;
205
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700206 // The minimum amount of time between successive GC requests for a process.
207 static final int GC_MIN_INTERVAL = 60*1000;
208
Dianne Hackborn287952c2010-09-22 22:34:31 -0700209 // The rate at which we check for apps using excessive power -- 15 mins.
210 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
211
212 // The minimum sample duration we will allow before deciding we have
213 // enough data on wake locks to start killing things.
214 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
215
216 // The minimum sample duration we will allow before deciding we have
217 // enough data on CPU usage to start killing things.
218 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 // How long we allow a receiver to run before giving up on it.
221 static final int BROADCAST_TIMEOUT = 10*1000;
222
223 // How long we wait for a service to finish executing.
224 static final int SERVICE_TIMEOUT = 20*1000;
225
226 // How long a service needs to be running until restarting its process
227 // is no longer considered to be a relaunch of the service.
228 static final int SERVICE_RESTART_DURATION = 5*1000;
229
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700230 // How long a service needs to be running until it will start back at
231 // SERVICE_RESTART_DURATION after being killed.
232 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
233
234 // Multiplying factor to increase restart duration time by, for each time
235 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
236 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
237
238 // The minimum amount of time between restarting services that we allow.
239 // That is, when multiple services are restarting, we won't allow each
240 // to restart less than this amount of time from the last one.
241 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 // Maximum amount of time for there to be no activity on a service before
244 // we consider it non-essential and allow its process to go on the
245 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700246 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247
248 // How long we wait until we timeout on key dispatching.
249 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 // How long we wait until we timeout on key dispatching during instrumentation.
252 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
253
Dan Egnor42471dd2010-01-07 17:25:22 -0800254 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255
256 static final String[] EMPTY_STRING_ARRAY = new String[0];
257
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700258 public ActivityStack mMainStack;
259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700261 * Description of a request to start a new activity, which has been held
262 * due to app switches being disabled.
263 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700264 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700265 ActivityRecord r;
266 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700267 Uri[] grantedUriPermissions;
268 int grantedMode;
269 boolean onlyIfNeeded;
270 }
271
272 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
273 = new ArrayList<PendingActivityLaunch>();
274
275 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 * List of all active broadcasts that are to be executed immediately
277 * (without waiting for another broadcast to finish). Currently this only
278 * contains broadcasts to registered receivers, to avoid spinning up
279 * a bunch of processes to execute IntentReceiver components.
280 */
281 final ArrayList<BroadcastRecord> mParallelBroadcasts
282 = new ArrayList<BroadcastRecord>();
283
284 /**
285 * List of all active broadcasts that are to be executed one at a time.
286 * The object at the top of the list is the currently activity broadcasts;
287 * those after it are waiting for the top to finish..
288 */
289 final ArrayList<BroadcastRecord> mOrderedBroadcasts
290 = new ArrayList<BroadcastRecord>();
291
292 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800293 * Historical data of past broadcasts, for debugging.
294 */
295 static final int MAX_BROADCAST_HISTORY = 100;
296 final BroadcastRecord[] mBroadcastHistory
297 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
298
299 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 * Set when we current have a BROADCAST_INTENT_MSG in flight.
301 */
302 boolean mBroadcastsScheduled = false;
303
304 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 * Activity we have told the window manager to have key focus.
306 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700307 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700308 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 * List of intents that were used to start the most recent tasks.
310 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700311 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312
313 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700314 * Process management.
315 */
316 final ProcessList mProcessList = new ProcessList();
317
318 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 * All of the applications we currently have running organized by name.
320 * The keys are strings of the application package name (as
321 * returned by the package manager), and the keys are ApplicationRecord
322 * objects.
323 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700324 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325
326 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700327 * The currently running heavy-weight process, if any.
328 */
329 ProcessRecord mHeavyWeightProcess = null;
330
331 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 * The last time that various processes have crashed.
333 */
334 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
335
336 /**
337 * Set of applications that we consider to be bad, and will reject
338 * incoming broadcasts from (which the user has no control over).
339 * Processes are added to this set when they have crashed twice within
340 * a minimum amount of time; they are removed from it when they are
341 * later restarted (hopefully due to some user action). The value is the
342 * time it was added to the list.
343 */
344 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
345
346 /**
347 * All of the processes we currently have running organized by pid.
348 * The keys are the pid running the application.
349 *
350 * <p>NOTE: This object is protected by its own lock, NOT the global
351 * activity manager lock!
352 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700353 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354
355 /**
356 * All of the processes that have been forced to be foreground. The key
357 * is the pid of the caller who requested it (we hold a death
358 * link on it).
359 */
360 abstract class ForegroundToken implements IBinder.DeathRecipient {
361 int pid;
362 IBinder token;
363 }
364 final SparseArray<ForegroundToken> mForegroundProcesses
365 = new SparseArray<ForegroundToken>();
366
367 /**
368 * List of records for processes that someone had tried to start before the
369 * system was ready. We don't start them at that point, but ensure they
370 * are started by the time booting is complete.
371 */
372 final ArrayList<ProcessRecord> mProcessesOnHold
373 = new ArrayList<ProcessRecord>();
374
375 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 * List of persistent applications that are in the process
377 * of being started.
378 */
379 final ArrayList<ProcessRecord> mPersistentStartingProcesses
380 = new ArrayList<ProcessRecord>();
381
382 /**
383 * Processes that are being forcibly torn down.
384 */
385 final ArrayList<ProcessRecord> mRemovedProcesses
386 = new ArrayList<ProcessRecord>();
387
388 /**
389 * List of running applications, sorted by recent usage.
390 * The first entry in the list is the least recently used.
391 * It contains ApplicationRecord objects. This list does NOT include
392 * any persistent application records (since we never want to exit them).
393 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800394 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 = new ArrayList<ProcessRecord>();
396
397 /**
398 * List of processes that should gc as soon as things are idle.
399 */
400 final ArrayList<ProcessRecord> mProcessesToGc
401 = new ArrayList<ProcessRecord>();
402
403 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800404 * This is the process holding what we currently consider to be
405 * the "home" activity.
406 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700407 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800408
409 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400410 * Packages that the user has asked to have run in screen size
411 * compatibility mode instead of filling the screen.
412 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700413 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400414
415 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 * Set of PendingResultRecord objects that are currently active.
417 */
418 final HashSet mPendingResultRecords = new HashSet();
419
420 /**
421 * Set of IntentSenderRecord objects that are currently active.
422 */
423 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
424 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
425
426 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800427 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700428 * already logged DropBox entries for. Guarded by itself. If
429 * something (rogue user app) forces this over
430 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
431 */
432 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
433 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
434
435 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700436 * Strict Mode background batched logging state.
437 *
438 * The string buffer is guarded by itself, and its lock is also
439 * used to determine if another batched write is already
440 * in-flight.
441 */
442 private final StringBuilder mStrictModeBuffer = new StringBuilder();
443
444 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700445 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
446 */
447 private boolean mPendingBroadcastTimeoutMessage;
448
449 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 * Intent broadcast that we have tried to start, but are
451 * waiting for its application's process to be created. We only
452 * need one (instead of a list) because we always process broadcasts
453 * one at a time, so no others can be started while waiting for this
454 * one.
455 */
456 BroadcastRecord mPendingBroadcast = null;
457
458 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700459 * The receiver index that is pending, to restart the broadcast if needed.
460 */
461 int mPendingBroadcastRecvIndex;
462
463 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 * Keeps track of all IIntentReceivers that have been registered for
465 * broadcasts. Hash keys are the receiver IBinder, hash value is
466 * a ReceiverList.
467 */
468 final HashMap mRegisteredReceivers = new HashMap();
469
470 /**
471 * Resolver for broadcast intents to registered receivers.
472 * Holds BroadcastFilter (subclass of IntentFilter).
473 */
474 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
475 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
476 @Override
477 protected boolean allowFilterResult(
478 BroadcastFilter filter, List<BroadcastFilter> dest) {
479 IBinder target = filter.receiverList.receiver.asBinder();
480 for (int i=dest.size()-1; i>=0; i--) {
481 if (dest.get(i).receiverList.receiver.asBinder() == target) {
482 return false;
483 }
484 }
485 return true;
486 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700487
488 @Override
489 protected String packageForFilter(BroadcastFilter filter) {
490 return filter.packageName;
491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 };
493
494 /**
495 * State of all active sticky broadcasts. Keys are the action of the
496 * sticky Intent, values are an ArrayList of all broadcasted intents with
497 * that action (which should usually be one).
498 */
499 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
500 new HashMap<String, ArrayList<Intent>>();
501
502 /**
503 * All currently running services.
504 */
505 final HashMap<ComponentName, ServiceRecord> mServices =
506 new HashMap<ComponentName, ServiceRecord>();
507
508 /**
509 * All currently running services indexed by the Intent used to start them.
510 */
511 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
512 new HashMap<Intent.FilterComparison, ServiceRecord>();
513
514 /**
515 * All currently bound service connections. Keys are the IBinder of
516 * the client's IServiceConnection.
517 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700518 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
519 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520
521 /**
522 * List of services that we have been asked to start,
523 * but haven't yet been able to. It is used to hold start requests
524 * while waiting for their corresponding application thread to get
525 * going.
526 */
527 final ArrayList<ServiceRecord> mPendingServices
528 = new ArrayList<ServiceRecord>();
529
530 /**
531 * List of services that are scheduled to restart following a crash.
532 */
533 final ArrayList<ServiceRecord> mRestartingServices
534 = new ArrayList<ServiceRecord>();
535
536 /**
537 * List of services that are in the process of being stopped.
538 */
539 final ArrayList<ServiceRecord> mStoppingServices
540 = new ArrayList<ServiceRecord>();
541
542 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700543 * Backup/restore process management
544 */
545 String mBackupAppName = null;
546 BackupRecord mBackupTarget = null;
547
548 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 * List of PendingThumbnailsRecord objects of clients who are still
550 * waiting to receive all of the thumbnails for a task.
551 */
552 final ArrayList mPendingThumbnails = new ArrayList();
553
554 /**
555 * List of HistoryRecord objects that have been finished and must
556 * still report back to a pending thumbnail receiver.
557 */
558 final ArrayList mCancelledThumbnails = new ArrayList();
559
560 /**
561 * All of the currently running global content providers. Keys are a
562 * string containing the provider name and values are a
563 * ContentProviderRecord object containing the data about it. Note
564 * that a single provider may be published under multiple names, so
565 * there may be multiple entries here for a single one in mProvidersByClass.
566 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700567 final HashMap<String, ContentProviderRecord> mProvidersByName
568 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569
570 /**
571 * All of the currently running global content providers. Keys are a
572 * string containing the provider's implementation class and values are a
573 * ContentProviderRecord object containing the data about it.
574 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700575 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
576 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577
578 /**
579 * List of content providers who have clients waiting for them. The
580 * application is currently being launched and the provider will be
581 * removed from this list once it is published.
582 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700583 final ArrayList<ContentProviderRecord> mLaunchingProviders
584 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585
586 /**
587 * Global set of specific Uri permissions that have been granted.
588 */
589 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
590 = new SparseArray<HashMap<Uri, UriPermission>>();
591
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800592 CoreSettingsObserver mCoreSettingsObserver;
593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 /**
595 * Thread-local storage used to carry caller permissions over through
596 * indirect content-provider access.
597 * @see #ActivityManagerService.openContentUri()
598 */
599 private class Identity {
600 public int pid;
601 public int uid;
602
603 Identity(int _pid, int _uid) {
604 pid = _pid;
605 uid = _uid;
606 }
607 }
608 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
609
610 /**
611 * All information we have collected about the runtime performance of
612 * any user id that can impact battery performance.
613 */
614 final BatteryStatsService mBatteryStatsService;
615
616 /**
617 * information about component usage
618 */
619 final UsageStatsService mUsageStatsService;
620
621 /**
622 * Current configuration information. HistoryRecord objects are given
623 * a reference to this object to indicate which configuration they are
624 * currently running in, so this object must be kept immutable.
625 */
626 Configuration mConfiguration = new Configuration();
627
628 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800629 * Current sequencing integer of the configuration, for skipping old
630 * configurations.
631 */
632 int mConfigurationSeq = 0;
633
634 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700635 * Hardware-reported OpenGLES version.
636 */
637 final int GL_ES_VERSION;
638
639 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 * List of initialization arguments to pass to all processes when binding applications to them.
641 * For example, references to the commonly used services.
642 */
643 HashMap<String, IBinder> mAppBindArgs;
644
645 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700646 * Temporary to avoid allocations. Protected by main lock.
647 */
648 final StringBuilder mStringBuilder = new StringBuilder(256);
649
650 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 * Used to control how we initialize the service.
652 */
653 boolean mStartRunning = false;
654 ComponentName mTopComponent;
655 String mTopAction;
656 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700657 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 boolean mSystemReady = false;
659 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700660 boolean mWaitingUpdate = false;
661 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700662 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700663 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664
665 Context mContext;
666
667 int mFactoryTest;
668
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700669 boolean mCheckedForSetup;
670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700672 * The time at which we will allow normal application switches again,
673 * after a call to {@link #stopAppSwitches()}.
674 */
675 long mAppSwitchesAllowedTime;
676
677 /**
678 * This is set to true after the first switch after mAppSwitchesAllowedTime
679 * is set; any switches after that will clear the time.
680 */
681 boolean mDidAppSwitch;
682
683 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700684 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700685 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700686 long mLastPowerCheckRealtime;
687
688 /**
689 * Last time (in uptime) at which we checked for power usage.
690 */
691 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700692
693 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 * Set while we are wanting to sleep, to prevent any
695 * activities from being started/resumed.
696 */
697 boolean mSleeping = false;
698
699 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700700 * Set if we are shutting down the system, similar to sleeping.
701 */
702 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703
704 /**
705 * Task identifier that activities are currently being started
706 * in. Incremented each time a new task is created.
707 * todo: Replace this with a TokenSpace class that generates non-repeating
708 * integers that won't wrap.
709 */
710 int mCurTask = 1;
711
712 /**
713 * Current sequence id for oom_adj computation traversal.
714 */
715 int mAdjSeq = 0;
716
717 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700718 * Current sequence id for process LRU updating.
719 */
720 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721
722 /**
723 * System monitoring: number of processes that died since the last
724 * N procs were started.
725 */
726 int[] mProcDeaths = new int[20];
727
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700728 /**
729 * This is set if we had to do a delayed dexopt of an app before launching
730 * it, to increasing the ANR timeouts in that case.
731 */
732 boolean mDidDexOpt;
733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 String mDebugApp = null;
735 boolean mWaitForDebugger = false;
736 boolean mDebugTransient = false;
737 String mOrigDebugApp = null;
738 boolean mOrigWaitForDebugger = false;
739 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700740 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700741 String mProfileApp = null;
742 ProcessRecord mProfileProc = null;
743 String mProfileFile;
744 ParcelFileDescriptor mProfileFd;
745 int mProfileType = 0;
746 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700748 final RemoteCallbackList<IActivityWatcher> mWatchers
749 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700750
751 final RemoteCallbackList<IProcessObserver> mProcessObservers
752 = new RemoteCallbackList<IProcessObserver>();
753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 /**
755 * Callback of last caller to {@link #requestPss}.
756 */
757 Runnable mRequestPssCallback;
758
759 /**
760 * Remaining processes for which we are waiting results from the last
761 * call to {@link #requestPss}.
762 */
763 final ArrayList<ProcessRecord> mRequestPssList
764 = new ArrayList<ProcessRecord>();
765
766 /**
767 * Runtime statistics collection thread. This object's lock is used to
768 * protect all related state.
769 */
770 final Thread mProcessStatsThread;
771
772 /**
773 * Used to collect process stats when showing not responding dialog.
774 * Protected by mProcessStatsThread.
775 */
776 final ProcessStats mProcessStats = new ProcessStats(
777 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700778 final AtomicLong mLastCpuTime = new AtomicLong(0);
779 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 long mLastWriteTime = 0;
782
783 /**
784 * Set to true after the system has finished booting.
785 */
786 boolean mBooted = false;
787
Dianne Hackborn7d608422011-08-07 16:24:18 -0700788 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700789 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790
791 WindowManagerService mWindowManager;
792
793 static ActivityManagerService mSelf;
794 static ActivityThread mSystemThread;
795
796 private final class AppDeathRecipient implements IBinder.DeathRecipient {
797 final ProcessRecord mApp;
798 final int mPid;
799 final IApplicationThread mAppThread;
800
801 AppDeathRecipient(ProcessRecord app, int pid,
802 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800803 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 TAG, "New death recipient " + this
805 + " for thread " + thread.asBinder());
806 mApp = app;
807 mPid = pid;
808 mAppThread = thread;
809 }
810
811 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800812 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 TAG, "Death received in " + this
814 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 synchronized(ActivityManagerService.this) {
816 appDiedLocked(mApp, mPid, mAppThread);
817 }
818 }
819 }
820
821 static final int SHOW_ERROR_MSG = 1;
822 static final int SHOW_NOT_RESPONDING_MSG = 2;
823 static final int SHOW_FACTORY_ERROR_MSG = 3;
824 static final int UPDATE_CONFIGURATION_MSG = 4;
825 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
826 static final int WAIT_FOR_DEBUGGER_MSG = 6;
827 static final int BROADCAST_INTENT_MSG = 7;
828 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 static final int SERVICE_TIMEOUT_MSG = 12;
830 static final int UPDATE_TIME_ZONE = 13;
831 static final int SHOW_UID_ERROR_MSG = 14;
832 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700834 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700835 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800836 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700837 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
838 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700839 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700840 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700841 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700842 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700843 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700844 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
845 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846
847 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700848 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849
850 final Handler mHandler = new Handler() {
851 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800852 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 //}
854
855 public void handleMessage(Message msg) {
856 switch (msg.what) {
857 case SHOW_ERROR_MSG: {
858 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 synchronized (ActivityManagerService.this) {
860 ProcessRecord proc = (ProcessRecord)data.get("app");
861 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800862 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863 return;
864 }
865 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700866 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800867 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 d.show();
869 proc.crashDialog = d;
870 } else {
871 // The device is asleep, so just pretend that the user
872 // saw a crash dialog and hit "force quit".
873 res.set(0);
874 }
875 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700876
877 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 } break;
879 case SHOW_NOT_RESPONDING_MSG: {
880 synchronized (ActivityManagerService.this) {
881 HashMap data = (HashMap) msg.obj;
882 ProcessRecord proc = (ProcessRecord)data.get("app");
883 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800884 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 return;
886 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800887
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700888 Intent intent = new Intent("android.intent.action.ANR");
889 if (!mProcessesReady) {
890 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
891 }
892 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800893 null, null, 0, null, null, null,
894 false, false, MY_PID, Process.SYSTEM_UID);
895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700897 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 d.show();
899 proc.anrDialog = d;
900 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700901
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700902 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700904 case SHOW_STRICT_MODE_VIOLATION_MSG: {
905 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
906 synchronized (ActivityManagerService.this) {
907 ProcessRecord proc = (ProcessRecord) data.get("app");
908 if (proc == null) {
909 Slog.e(TAG, "App not found when showing strict mode dialog.");
910 break;
911 }
912 if (proc.crashDialog != null) {
913 Slog.e(TAG, "App already has strict mode dialog: " + proc);
914 return;
915 }
916 AppErrorResult res = (AppErrorResult) data.get("result");
917 if (!mSleeping && !mShuttingDown) {
918 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
919 d.show();
920 proc.crashDialog = d;
921 } else {
922 // The device is asleep, so just pretend that the user
923 // saw a crash dialog and hit "force quit".
924 res.set(0);
925 }
926 }
927 ensureBootCompleted();
928 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 case SHOW_FACTORY_ERROR_MSG: {
930 Dialog d = new FactoryErrorDialog(
931 mContext, msg.getData().getCharSequence("msg"));
932 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700933 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 } break;
935 case UPDATE_CONFIGURATION_MSG: {
936 final ContentResolver resolver = mContext.getContentResolver();
937 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
938 } break;
939 case GC_BACKGROUND_PROCESSES_MSG: {
940 synchronized (ActivityManagerService.this) {
941 performAppGcsIfAppropriateLocked();
942 }
943 } break;
944 case WAIT_FOR_DEBUGGER_MSG: {
945 synchronized (ActivityManagerService.this) {
946 ProcessRecord app = (ProcessRecord)msg.obj;
947 if (msg.arg1 != 0) {
948 if (!app.waitedForDebugger) {
949 Dialog d = new AppWaitingForDebuggerDialog(
950 ActivityManagerService.this,
951 mContext, app);
952 app.waitDialog = d;
953 app.waitedForDebugger = true;
954 d.show();
955 }
956 } else {
957 if (app.waitDialog != null) {
958 app.waitDialog.dismiss();
959 app.waitDialog = null;
960 }
961 }
962 }
963 } break;
964 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800965 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 TAG, "Received BROADCAST_INTENT_MSG");
967 processNextBroadcast(true);
968 } break;
969 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700970 synchronized (ActivityManagerService.this) {
971 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700975 if (mDidDexOpt) {
976 mDidDexOpt = false;
977 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
978 nmsg.obj = msg.obj;
979 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
980 return;
981 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 serviceTimeout((ProcessRecord)msg.obj);
983 } break;
984 case UPDATE_TIME_ZONE: {
985 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800986 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
987 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 if (r.thread != null) {
989 try {
990 r.thread.updateTimeZone();
991 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800992 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 }
994 }
995 }
996 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700997 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700998 case CLEAR_DNS_CACHE: {
999 synchronized (ActivityManagerService.this) {
1000 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1001 ProcessRecord r = mLruProcesses.get(i);
1002 if (r.thread != null) {
1003 try {
1004 r.thread.clearDnsCache();
1005 } catch (RemoteException ex) {
1006 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1007 }
1008 }
1009 }
1010 }
1011 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001012 case UPDATE_HTTP_PROXY: {
1013 ProxyProperties proxy = (ProxyProperties)msg.obj;
1014 String host = "";
1015 String port = "";
1016 String exclList = "";
1017 if (proxy != null) {
1018 host = proxy.getHost();
1019 port = Integer.toString(proxy.getPort());
1020 exclList = proxy.getExclusionList();
1021 }
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.setHttpProxy(host, port, exclList);
1028 } catch (RemoteException ex) {
1029 Slog.w(TAG, "Failed to update http proxy for: " +
1030 r.info.processName);
1031 }
1032 }
1033 }
1034 }
1035 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001036 case SHOW_UID_ERROR_MSG: {
1037 // XXX This is a temporary dialog, no need to localize.
1038 AlertDialog d = new BaseErrorDialog(mContext);
1039 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1040 d.setCancelable(false);
1041 d.setTitle("System UIDs Inconsistent");
1042 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 +02001043 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1045 mUidAlert = d;
1046 d.show();
1047 } break;
1048 case IM_FEELING_LUCKY_MSG: {
1049 if (mUidAlert != null) {
1050 mUidAlert.dismiss();
1051 mUidAlert = null;
1052 }
1053 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001055 if (mDidDexOpt) {
1056 mDidDexOpt = false;
1057 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1058 nmsg.obj = msg.obj;
1059 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1060 return;
1061 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 ProcessRecord app = (ProcessRecord)msg.obj;
1063 synchronized (ActivityManagerService.this) {
1064 processStartTimedOutLocked(app);
1065 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001066 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001067 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1068 synchronized (ActivityManagerService.this) {
1069 doPendingActivityLaunchesLocked(true);
1070 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001071 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001072 case KILL_APPLICATION_MSG: {
1073 synchronized (ActivityManagerService.this) {
1074 int uid = msg.arg1;
1075 boolean restart = (msg.arg2 == 1);
1076 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001077 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001078 }
1079 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001080 case FINALIZE_PENDING_INTENT_MSG: {
1081 ((PendingIntentRecord)msg.obj).completeFinalize();
1082 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001083 case POST_HEAVY_NOTIFICATION_MSG: {
1084 INotificationManager inm = NotificationManager.getService();
1085 if (inm == null) {
1086 return;
1087 }
1088
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001089 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001090 ProcessRecord process = root.app;
1091 if (process == null) {
1092 return;
1093 }
1094
1095 try {
1096 Context context = mContext.createPackageContext(process.info.packageName, 0);
1097 String text = mContext.getString(R.string.heavy_weight_notification,
1098 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1099 Notification notification = new Notification();
1100 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1101 notification.when = 0;
1102 notification.flags = Notification.FLAG_ONGOING_EVENT;
1103 notification.tickerText = text;
1104 notification.defaults = 0; // please be quiet
1105 notification.sound = null;
1106 notification.vibrate = null;
1107 notification.setLatestEventInfo(context, text,
1108 mContext.getText(R.string.heavy_weight_notification_detail),
1109 PendingIntent.getActivity(mContext, 0, root.intent,
1110 PendingIntent.FLAG_CANCEL_CURRENT));
1111
1112 try {
1113 int[] outId = new int[1];
1114 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1115 notification, outId);
1116 } catch (RuntimeException e) {
1117 Slog.w(ActivityManagerService.TAG,
1118 "Error showing notification for heavy-weight app", e);
1119 } catch (RemoteException e) {
1120 }
1121 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001122 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001123 }
1124 } break;
1125 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1126 INotificationManager inm = NotificationManager.getService();
1127 if (inm == null) {
1128 return;
1129 }
1130 try {
1131 inm.cancelNotification("android",
1132 R.string.heavy_weight_notification);
1133 } catch (RuntimeException e) {
1134 Slog.w(ActivityManagerService.TAG,
1135 "Error canceling notification for service", e);
1136 } catch (RemoteException e) {
1137 }
1138 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001139 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1140 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001141 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001142 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001143 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1144 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001145 }
1146 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001147 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1148 synchronized (ActivityManagerService.this) {
1149 ActivityRecord ar = (ActivityRecord)msg.obj;
1150 if (mCompatModeDialog != null) {
1151 if (mCompatModeDialog.mAppInfo.packageName.equals(
1152 ar.info.applicationInfo.packageName)) {
1153 return;
1154 }
1155 mCompatModeDialog.dismiss();
1156 mCompatModeDialog = null;
1157 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001158 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001159 if (mCompatModePackages.getPackageAskCompatModeLocked(
1160 ar.packageName)) {
1161 int mode = mCompatModePackages.computeCompatModeLocked(
1162 ar.info.applicationInfo);
1163 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1164 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1165 mCompatModeDialog = new CompatModeDialog(
1166 ActivityManagerService.this, mContext,
1167 ar.info.applicationInfo);
1168 mCompatModeDialog.show();
1169 }
1170 }
1171 }
1172 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001173 break;
1174 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001175 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001176 final int pid = msg.arg1;
1177 final int uid = msg.arg2;
1178 final boolean foregroundActivities = (Boolean) msg.obj;
1179 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001180 break;
1181 }
1182 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001183 final int pid = msg.arg1;
1184 final int uid = msg.arg2;
1185 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001186 break;
1187 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001188 }
1189 }
1190 };
1191
1192 public static void setSystemProcess() {
1193 try {
1194 ActivityManagerService m = mSelf;
1195
1196 ServiceManager.addService("activity", m);
1197 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001198 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199 if (MONITOR_CPU_USAGE) {
1200 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001202 ServiceManager.addService("permission", new PermissionController(m));
1203
1204 ApplicationInfo info =
1205 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001206 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001207 mSystemThread.installSystemApplicationInfo(info);
1208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 synchronized (mSelf) {
1210 ProcessRecord app = mSelf.newProcessRecordLocked(
1211 mSystemThread.getApplicationThread(), info,
1212 info.processName);
1213 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001214 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001215 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1217 synchronized (mSelf.mPidsSelfLocked) {
1218 mSelf.mPidsSelfLocked.put(app.pid, app);
1219 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001220 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 }
1222 } catch (PackageManager.NameNotFoundException e) {
1223 throw new RuntimeException(
1224 "Unable to find android system package", e);
1225 }
1226 }
1227
1228 public void setWindowManager(WindowManagerService wm) {
1229 mWindowManager = wm;
1230 }
1231
1232 public static final Context main(int factoryTest) {
1233 AThread thr = new AThread();
1234 thr.start();
1235
1236 synchronized (thr) {
1237 while (thr.mService == null) {
1238 try {
1239 thr.wait();
1240 } catch (InterruptedException e) {
1241 }
1242 }
1243 }
1244
1245 ActivityManagerService m = thr.mService;
1246 mSelf = m;
1247 ActivityThread at = ActivityThread.systemMain();
1248 mSystemThread = at;
1249 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001250 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 m.mContext = context;
1252 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001253 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254
1255 m.mBatteryStatsService.publish(context);
1256 m.mUsageStatsService.publish(context);
1257
1258 synchronized (thr) {
1259 thr.mReady = true;
1260 thr.notifyAll();
1261 }
1262
1263 m.startRunning(null, null, null, null);
1264
1265 return context;
1266 }
1267
1268 public static ActivityManagerService self() {
1269 return mSelf;
1270 }
1271
1272 static class AThread extends Thread {
1273 ActivityManagerService mService;
1274 boolean mReady = false;
1275
1276 public AThread() {
1277 super("ActivityManager");
1278 }
1279
1280 public void run() {
1281 Looper.prepare();
1282
1283 android.os.Process.setThreadPriority(
1284 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001285 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286
1287 ActivityManagerService m = new ActivityManagerService();
1288
1289 synchronized (this) {
1290 mService = m;
1291 notifyAll();
1292 }
1293
1294 synchronized (this) {
1295 while (!mReady) {
1296 try {
1297 wait();
1298 } catch (InterruptedException e) {
1299 }
1300 }
1301 }
1302
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001303 // For debug builds, log event loop stalls to dropbox for analysis.
1304 if (StrictMode.conditionallyEnableDebugLogging()) {
1305 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1306 }
1307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 Looper.loop();
1309 }
1310 }
1311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001312 static class MemBinder extends Binder {
1313 ActivityManagerService mActivityManagerService;
1314 MemBinder(ActivityManagerService activityManagerService) {
1315 mActivityManagerService = activityManagerService;
1316 }
1317
1318 @Override
1319 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001320 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 }
1322 }
1323
Chet Haase9c1e23b2011-03-24 10:51:31 -07001324 static class GraphicsBinder extends Binder {
1325 ActivityManagerService mActivityManagerService;
1326 GraphicsBinder(ActivityManagerService activityManagerService) {
1327 mActivityManagerService = activityManagerService;
1328 }
1329
1330 @Override
1331 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001332 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001333 }
1334 }
1335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 static class CpuBinder extends Binder {
1337 ActivityManagerService mActivityManagerService;
1338 CpuBinder(ActivityManagerService activityManagerService) {
1339 mActivityManagerService = activityManagerService;
1340 }
1341
1342 @Override
1343 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1344 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001345 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1346 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1347 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 }
1349 }
1350 }
1351
1352 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001353 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 File dataDir = Environment.getDataDirectory();
1356 File systemDir = new File(dataDir, "system");
1357 systemDir.mkdirs();
1358 mBatteryStatsService = new BatteryStatsService(new File(
1359 systemDir, "batterystats.bin").toString());
1360 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001361 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001362 mOnBattery = DEBUG_POWER ? true
1363 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001364 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001366 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001367 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368
Jack Palevichb90d28c2009-07-22 15:35:24 -07001369 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1370 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1371
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001372 mConfiguration.setToDefaults();
1373 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 mProcessStats.init();
1375
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001376 mCompatModePackages = new CompatModePackages(this, systemDir);
1377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001378 // Add ourself to the Watchdog monitors.
1379 Watchdog.getInstance().addMonitor(this);
1380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001381 mProcessStatsThread = new Thread("ProcessStats") {
1382 public void run() {
1383 while (true) {
1384 try {
1385 try {
1386 synchronized(this) {
1387 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001388 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001390 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 // + ", write delay=" + nextWriteDelay);
1392 if (nextWriteDelay < nextCpuDelay) {
1393 nextCpuDelay = nextWriteDelay;
1394 }
1395 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001396 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 this.wait(nextCpuDelay);
1398 }
1399 }
1400 } catch (InterruptedException e) {
1401 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 updateCpuStatsNow();
1403 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001404 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 }
1406 }
1407 }
1408 };
1409 mProcessStatsThread.start();
1410 }
1411
1412 @Override
1413 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1414 throws RemoteException {
1415 try {
1416 return super.onTransact(code, data, reply, flags);
1417 } catch (RuntimeException e) {
1418 // The activity manager only throws security exceptions, so let's
1419 // log all others.
1420 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001421 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 }
1423 throw e;
1424 }
1425 }
1426
1427 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001428 final long now = SystemClock.uptimeMillis();
1429 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1430 return;
1431 }
1432 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1433 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 mProcessStatsThread.notify();
1435 }
1436 }
1437 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 void updateCpuStatsNow() {
1440 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001441 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001442 final long now = SystemClock.uptimeMillis();
1443 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001445 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001446 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1447 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001448 haveNewCpuStats = true;
1449 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001450 //Slog.i(TAG, mProcessStats.printCurrentState());
1451 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 // + mProcessStats.getTotalCpuPercent() + "%");
1453
Joe Onorato8a9b2202010-02-26 18:56:32 -08001454 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001455 if ("true".equals(SystemProperties.get("events.cpu"))) {
1456 int user = mProcessStats.getLastUserTime();
1457 int system = mProcessStats.getLastSystemTime();
1458 int iowait = mProcessStats.getLastIoWaitTime();
1459 int irq = mProcessStats.getLastIrqTime();
1460 int softIrq = mProcessStats.getLastSoftIrqTime();
1461 int idle = mProcessStats.getLastIdleTime();
1462
1463 int total = user + system + iowait + irq + softIrq + idle;
1464 if (total == 0) total = 1;
1465
Doug Zongker2bec3d42009-12-04 12:52:44 -08001466 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 ((user+system+iowait+irq+softIrq) * 100) / total,
1468 (user * 100) / total,
1469 (system * 100) / total,
1470 (iowait * 100) / total,
1471 (irq * 100) / total,
1472 (softIrq * 100) / total);
1473 }
1474 }
1475
Amith Yamasanie43530a2009-08-21 13:11:37 -07001476 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001477 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001478 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 synchronized(mPidsSelfLocked) {
1480 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001481 if (mOnBattery) {
1482 int perc = bstats.startAddingCpuLocked();
1483 int totalUTime = 0;
1484 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001485 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001487 ProcessStats.Stats st = mProcessStats.getStats(i);
1488 if (!st.working) {
1489 continue;
1490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001492 int otherUTime = (st.rel_utime*perc)/100;
1493 int otherSTime = (st.rel_stime*perc)/100;
1494 totalUTime += otherUTime;
1495 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 if (pr != null) {
1497 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001498 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1499 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001500 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001501 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001502 } else {
1503 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001504 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001505 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001506 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1507 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001508 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 }
1511 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001512 bstats.finishAddingCpuLocked(perc, totalUTime,
1513 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514 }
1515 }
1516 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1519 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001520 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 }
1522 }
1523 }
1524 }
1525
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001526 @Override
1527 public void batteryNeedsCpuUpdate() {
1528 updateCpuStatsNow();
1529 }
1530
1531 @Override
1532 public void batteryPowerChanged(boolean onBattery) {
1533 // When plugging in, update the CPU stats first before changing
1534 // the plug state.
1535 updateCpuStatsNow();
1536 synchronized (this) {
1537 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001538 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001539 }
1540 }
1541 }
1542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 /**
1544 * Initialize the application bind args. These are passed to each
1545 * process when the bindApplication() IPC is sent to the process. They're
1546 * lazily setup to make sure the services are running when they're asked for.
1547 */
1548 private HashMap<String, IBinder> getCommonServicesLocked() {
1549 if (mAppBindArgs == null) {
1550 mAppBindArgs = new HashMap<String, IBinder>();
1551
1552 // Setup the application init args
1553 mAppBindArgs.put("package", ServiceManager.getService("package"));
1554 mAppBindArgs.put("window", ServiceManager.getService("window"));
1555 mAppBindArgs.put(Context.ALARM_SERVICE,
1556 ServiceManager.getService(Context.ALARM_SERVICE));
1557 }
1558 return mAppBindArgs;
1559 }
1560
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001561 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 if (mFocusedActivity != r) {
1563 mFocusedActivity = r;
1564 mWindowManager.setFocusedApp(r, true);
1565 }
1566 }
1567
Dianne Hackborn906497c2010-05-10 15:57:38 -07001568 private final void updateLruProcessInternalLocked(ProcessRecord app,
1569 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001571 int lrui = mLruProcesses.indexOf(app);
1572 if (lrui >= 0) mLruProcesses.remove(lrui);
1573
1574 int i = mLruProcesses.size()-1;
1575 int skipTop = 0;
1576
Dianne Hackborn906497c2010-05-10 15:57:38 -07001577 app.lruSeq = mLruSeq;
1578
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001579 // compute the new weight for this process.
1580 if (updateActivityTime) {
1581 app.lastActivityTime = SystemClock.uptimeMillis();
1582 }
1583 if (app.activities.size() > 0) {
1584 // If this process has activities, we more strongly want to keep
1585 // it around.
1586 app.lruWeight = app.lastActivityTime;
1587 } else if (app.pubProviders.size() > 0) {
1588 // If this process contains content providers, we want to keep
1589 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001590 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001591 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001592 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001593 } else {
1594 // If this process doesn't have activities, we less strongly
1595 // want to keep it around, and generally want to avoid getting
1596 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001597 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001598 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001599 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001600 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001601
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001602 while (i >= 0) {
1603 ProcessRecord p = mLruProcesses.get(i);
1604 // If this app shouldn't be in front of the first N background
1605 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001606 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001607 skipTop--;
1608 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001609 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001610 mLruProcesses.add(i+1, app);
1611 break;
1612 }
1613 i--;
1614 }
1615 if (i < 0) {
1616 mLruProcesses.add(0, app);
1617 }
1618
Dianne Hackborn906497c2010-05-10 15:57:38 -07001619 // If the app is currently using a content provider or service,
1620 // bump those processes as well.
1621 if (app.connections.size() > 0) {
1622 for (ConnectionRecord cr : app.connections) {
1623 if (cr.binding != null && cr.binding.service != null
1624 && cr.binding.service.app != null
1625 && cr.binding.service.app.lruSeq != mLruSeq) {
1626 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1627 updateActivityTime, i+1);
1628 }
1629 }
1630 }
1631 if (app.conProviders.size() > 0) {
1632 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1633 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1634 updateLruProcessInternalLocked(cpr.app, oomAdj,
1635 updateActivityTime, i+1);
1636 }
1637 }
1638 }
1639
Joe Onorato8a9b2202010-02-26 18:56:32 -08001640 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001641 if (oomAdj) {
1642 updateOomAdjLocked();
1643 }
1644 }
1645
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001646 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001647 boolean oomAdj, boolean updateActivityTime) {
1648 mLruSeq++;
1649 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1650 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001651
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001652 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 String processName, int uid) {
1654 if (uid == Process.SYSTEM_UID) {
1655 // The system gets to run in any process. If there are multiple
1656 // processes with the same uid, just pick the first (this
1657 // should never happen).
1658 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1659 processName);
1660 return procs != null ? procs.valueAt(0) : null;
1661 }
1662 ProcessRecord proc = mProcessNames.get(processName, uid);
1663 return proc;
1664 }
1665
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001666 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001667 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001668 try {
1669 if (pm.performDexOpt(packageName)) {
1670 mDidDexOpt = true;
1671 }
1672 } catch (RemoteException e) {
1673 }
1674 }
1675
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001676 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677 int transit = mWindowManager.getPendingAppTransition();
1678 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1679 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1680 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1681 }
1682
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001683 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001684 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001685 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1687 // We don't have to do anything more if:
1688 // (1) There is an existing application record; and
1689 // (2) The caller doesn't think it is dead, OR there is no thread
1690 // object attached to it so we know it couldn't have crashed; and
1691 // (3) There is a pid assigned to it, so it is either starting or
1692 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001693 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001694 + " app=" + app + " knownToBeDead=" + knownToBeDead
1695 + " thread=" + (app != null ? app.thread : null)
1696 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001697 if (app != null && app.pid > 0) {
1698 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001699 // We already have the app running, or are waiting for it to
1700 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001701 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001702 // If this is a new package in the process, add the package to the list
1703 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001704 return app;
1705 } else {
1706 // An application record is attached to a previous process,
1707 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001708 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001709 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001710 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001713 String hostingNameStr = hostingName != null
1714 ? hostingName.flattenToShortString() : null;
1715
1716 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1717 // If we are in the background, then check to see if this process
1718 // is bad. If so, we will just silently fail.
1719 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001720 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1721 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 return null;
1723 }
1724 } else {
1725 // When the user is explicitly starting a process, then clear its
1726 // crash count so that we won't make it bad until they see at
1727 // least one crash dialog again, and make the process good again
1728 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001729 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1730 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001731 mProcessCrashTimes.remove(info.processName, info.uid);
1732 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001733 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001734 info.processName);
1735 mBadProcesses.remove(info.processName, info.uid);
1736 if (app != null) {
1737 app.bad = false;
1738 }
1739 }
1740 }
1741
1742 if (app == null) {
1743 app = newProcessRecordLocked(null, info, processName);
1744 mProcessNames.put(processName, info.uid, app);
1745 } else {
1746 // If this is a new package in the process, add the package to the list
1747 app.addPackage(info.packageName);
1748 }
1749
1750 // If the system is not ready yet, then hold off on starting this
1751 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001752 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001753 && !isAllowedWhileBooting(info)
1754 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 if (!mProcessesOnHold.contains(app)) {
1756 mProcessesOnHold.add(app);
1757 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001758 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001759 return app;
1760 }
1761
1762 startProcessLocked(app, hostingType, hostingNameStr);
1763 return (app.pid != 0) ? app : null;
1764 }
1765
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001766 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1767 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1768 }
1769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001770 private final void startProcessLocked(ProcessRecord app,
1771 String hostingType, String hostingNameStr) {
1772 if (app.pid > 0 && app.pid != MY_PID) {
1773 synchronized (mPidsSelfLocked) {
1774 mPidsSelfLocked.remove(app.pid);
1775 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1776 }
1777 app.pid = 0;
1778 }
1779
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001780 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1781 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001782 mProcessesOnHold.remove(app);
1783
1784 updateCpuStats();
1785
1786 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1787 mProcDeaths[0] = 0;
1788
1789 try {
1790 int uid = app.info.uid;
1791 int[] gids = null;
1792 try {
1793 gids = mContext.getPackageManager().getPackageGids(
1794 app.info.packageName);
1795 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001796 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001797 }
1798 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1799 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1800 && mTopComponent != null
1801 && app.processName.equals(mTopComponent.getPackageName())) {
1802 uid = 0;
1803 }
1804 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1805 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1806 uid = 0;
1807 }
1808 }
1809 int debugFlags = 0;
1810 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1811 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001812 // Also turn on CheckJNI for debuggable apps. It's quite
1813 // awkward to turn on otherwise.
1814 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001815 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001816 // Run the app in safe mode if its manifest requests so or the
1817 // system is booted in safe mode.
1818 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1819 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001820 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1821 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1823 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1824 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001825 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1826 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001828 if ("1".equals(SystemProperties.get("debug.assert"))) {
1829 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1830 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001831
1832 // Start the process. It will either succeed and return a result containing
1833 // the PID of the new process, or else throw a RuntimeException.
1834 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001835 app.processName, uid, uid, gids, debugFlags,
1836 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001838 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1839 synchronized (bs) {
1840 if (bs.isOnBattery()) {
1841 app.batteryStats.incStartsLocked();
1842 }
1843 }
1844
Jeff Brown3f9dd282011-07-08 20:02:19 -07001845 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 app.processName, hostingType,
1847 hostingNameStr != null ? hostingNameStr : "");
1848
1849 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001850 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001851 }
1852
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001853 StringBuilder buf = mStringBuilder;
1854 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001855 buf.append("Start proc ");
1856 buf.append(app.processName);
1857 buf.append(" for ");
1858 buf.append(hostingType);
1859 if (hostingNameStr != null) {
1860 buf.append(" ");
1861 buf.append(hostingNameStr);
1862 }
1863 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001864 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865 buf.append(" uid=");
1866 buf.append(uid);
1867 buf.append(" gids={");
1868 if (gids != null) {
1869 for (int gi=0; gi<gids.length; gi++) {
1870 if (gi != 0) buf.append(", ");
1871 buf.append(gids[gi]);
1872
1873 }
1874 }
1875 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001876 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001877 app.pid = startResult.pid;
1878 app.usingWrapper = startResult.usingWrapper;
1879 app.removed = false;
1880 synchronized (mPidsSelfLocked) {
1881 this.mPidsSelfLocked.put(startResult.pid, app);
1882 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1883 msg.obj = app;
1884 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1885 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001886 }
1887 } catch (RuntimeException e) {
1888 // XXX do better error recovery.
1889 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001890 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001891 }
1892 }
1893
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001894 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001895 if (resumed) {
1896 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1897 } else {
1898 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1899 }
1900 }
1901
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001902 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001903 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1904 && mTopAction == null) {
1905 // We are running in factory test mode, but unable to find
1906 // the factory test app, so just sit around displaying the
1907 // error message and don't try to start anything.
1908 return false;
1909 }
1910 Intent intent = new Intent(
1911 mTopAction,
1912 mTopData != null ? Uri.parse(mTopData) : null);
1913 intent.setComponent(mTopComponent);
1914 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1915 intent.addCategory(Intent.CATEGORY_HOME);
1916 }
1917 ActivityInfo aInfo =
1918 intent.resolveActivityInfo(mContext.getPackageManager(),
1919 STOCK_PM_FLAGS);
1920 if (aInfo != null) {
1921 intent.setComponent(new ComponentName(
1922 aInfo.applicationInfo.packageName, aInfo.name));
1923 // Don't do this if the home app is currently being
1924 // instrumented.
1925 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1926 aInfo.applicationInfo.uid);
1927 if (app == null || app.instrumentationClass == null) {
1928 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001929 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001930 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001931 }
1932 }
1933
1934
1935 return true;
1936 }
1937
1938 /**
1939 * Starts the "new version setup screen" if appropriate.
1940 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001941 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001942 // Only do this once per boot.
1943 if (mCheckedForSetup) {
1944 return;
1945 }
1946
1947 // We will show this screen if the current one is a different
1948 // version than the last one shown, and we are not running in
1949 // low-level factory test mode.
1950 final ContentResolver resolver = mContext.getContentResolver();
1951 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1952 Settings.Secure.getInt(resolver,
1953 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1954 mCheckedForSetup = true;
1955
1956 // See if we should be showing the platform update setup UI.
1957 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1958 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1959 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1960
1961 // We don't allow third party apps to replace this.
1962 ResolveInfo ri = null;
1963 for (int i=0; ris != null && i<ris.size(); i++) {
1964 if ((ris.get(i).activityInfo.applicationInfo.flags
1965 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1966 ri = ris.get(i);
1967 break;
1968 }
1969 }
1970
1971 if (ri != null) {
1972 String vers = ri.activityInfo.metaData != null
1973 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
1974 : null;
1975 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
1976 vers = ri.activityInfo.applicationInfo.metaData.getString(
1977 Intent.METADATA_SETUP_VERSION);
1978 }
1979 String lastVers = Settings.Secure.getString(
1980 resolver, Settings.Secure.LAST_SETUP_SHOWN);
1981 if (vers != null && !vers.equals(lastVers)) {
1982 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1983 intent.setComponent(new ComponentName(
1984 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001985 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001986 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001987 }
1988 }
1989 }
1990 }
1991
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001992 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001993 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001994 }
1995
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001996 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001997 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001998 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
1999 }
2000 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002001
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002002 public void setFrontActivityScreenCompatMode(int mode) {
2003 synchronized (this) {
2004 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2005 }
2006 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002007
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002008 public int getPackageScreenCompatMode(String packageName) {
2009 synchronized (this) {
2010 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2011 }
2012 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002013
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002014 public void setPackageScreenCompatMode(String packageName, int mode) {
2015 synchronized (this) {
2016 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002017 }
2018 }
2019
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002020 public boolean getPackageAskScreenCompat(String packageName) {
2021 synchronized (this) {
2022 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2023 }
2024 }
2025
2026 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2027 synchronized (this) {
2028 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2029 }
2030 }
2031
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002032 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002033 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002034
2035 final int identHash = System.identityHashCode(r);
2036 updateUsageStats(r, true);
2037
2038 int i = mWatchers.beginBroadcast();
2039 while (i > 0) {
2040 i--;
2041 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2042 if (w != null) {
2043 try {
2044 w.activityResuming(identHash);
2045 } catch (RemoteException e) {
2046 }
2047 }
2048 }
2049 mWatchers.finishBroadcast();
2050 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002051
Jeff Sharkeya4620792011-05-20 15:29:23 -07002052 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2053 int i = mProcessObservers.beginBroadcast();
2054 while (i > 0) {
2055 i--;
2056 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2057 if (observer != null) {
2058 try {
2059 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2060 } catch (RemoteException e) {
2061 }
2062 }
2063 }
2064 mProcessObservers.finishBroadcast();
2065 }
2066
2067 private void dispatchProcessDied(int pid, int uid) {
2068 int i = mProcessObservers.beginBroadcast();
2069 while (i > 0) {
2070 i--;
2071 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2072 if (observer != null) {
2073 try {
2074 observer.onProcessDied(pid, uid);
2075 } catch (RemoteException e) {
2076 }
2077 }
2078 }
2079 mProcessObservers.finishBroadcast();
2080 }
2081
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002082 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002083 final int N = mPendingActivityLaunches.size();
2084 if (N <= 0) {
2085 return;
2086 }
2087 for (int i=0; i<N; i++) {
2088 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002089 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002090 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2091 doResume && i == (N-1));
2092 }
2093 mPendingActivityLaunches.clear();
2094 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002095
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002096 public final int startActivity(IApplicationThread caller,
2097 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2098 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002099 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2100 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002101 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002102 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002103 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2104 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002105 }
2106
2107 public final WaitResult startActivityAndWait(IApplicationThread caller,
2108 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2109 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002110 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2111 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002112 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002113 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002114 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002115 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2116 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002117 return res;
2118 }
2119
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002120 public final int startActivityWithConfig(IApplicationThread caller,
2121 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2122 int grantedMode, IBinder resultTo,
2123 String resultWho, int requestCode, boolean onlyIfNeeded,
2124 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002125 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002126 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002127 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002128 }
2129
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002130 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002131 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002132 IBinder resultTo, String resultWho, int requestCode,
2133 int flagsMask, int flagsValues) {
2134 // Refuse possible leaked file descriptors
2135 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2136 throw new IllegalArgumentException("File descriptors passed in Intent");
2137 }
2138
2139 IIntentSender sender = intent.getTarget();
2140 if (!(sender instanceof PendingIntentRecord)) {
2141 throw new IllegalArgumentException("Bad PendingIntent object");
2142 }
2143
2144 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002145
2146 synchronized (this) {
2147 // If this is coming from the currently resumed activity, it is
2148 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002149 if (mMainStack.mResumedActivity != null
2150 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002151 Binder.getCallingUid()) {
2152 mAppSwitchesAllowedTime = 0;
2153 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002154 }
2155
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002156 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002157 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2158 }
2159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002160 public boolean startNextMatchingActivity(IBinder callingActivity,
2161 Intent intent) {
2162 // Refuse possible leaked file descriptors
2163 if (intent != null && intent.hasFileDescriptors() == true) {
2164 throw new IllegalArgumentException("File descriptors passed in Intent");
2165 }
2166
2167 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002168 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2169 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002170 return false;
2171 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002172 if (r.app == null || r.app.thread == null) {
2173 // The caller is not running... d'oh!
2174 return false;
2175 }
2176 intent = new Intent(intent);
2177 // The caller is not allowed to change the data.
2178 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2179 // And we are resetting to find the next component...
2180 intent.setComponent(null);
2181
2182 ActivityInfo aInfo = null;
2183 try {
2184 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002185 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002186 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002187 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002188
2189 // Look for the original activity in the list...
2190 final int N = resolves != null ? resolves.size() : 0;
2191 for (int i=0; i<N; i++) {
2192 ResolveInfo rInfo = resolves.get(i);
2193 if (rInfo.activityInfo.packageName.equals(r.packageName)
2194 && rInfo.activityInfo.name.equals(r.info.name)) {
2195 // We found the current one... the next matching is
2196 // after it.
2197 i++;
2198 if (i<N) {
2199 aInfo = resolves.get(i).activityInfo;
2200 }
2201 break;
2202 }
2203 }
2204 } catch (RemoteException e) {
2205 }
2206
2207 if (aInfo == null) {
2208 // Nobody who is next!
2209 return false;
2210 }
2211
2212 intent.setComponent(new ComponentName(
2213 aInfo.applicationInfo.packageName, aInfo.name));
2214 intent.setFlags(intent.getFlags()&~(
2215 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2216 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2217 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2218 Intent.FLAG_ACTIVITY_NEW_TASK));
2219
2220 // Okay now we need to start the new activity, replacing the
2221 // currently running activity. This is a little tricky because
2222 // we want to start the new one as if the current one is finished,
2223 // but not finish the current one first so that there is no flicker.
2224 // And thus...
2225 final boolean wasFinishing = r.finishing;
2226 r.finishing = true;
2227
2228 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002229 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002230 final String resultWho = r.resultWho;
2231 final int requestCode = r.requestCode;
2232 r.resultTo = null;
2233 if (resultTo != null) {
2234 resultTo.removeResultsLocked(r, resultWho, requestCode);
2235 }
2236
2237 final long origId = Binder.clearCallingIdentity();
2238 // XXX we are not dealing with propagating grantedUriPermissions...
2239 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002240 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002241 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002242 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002243 Binder.restoreCallingIdentity(origId);
2244
2245 r.finishing = wasFinishing;
2246 if (res != START_SUCCESS) {
2247 return false;
2248 }
2249 return true;
2250 }
2251 }
2252
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002253 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 Intent intent, String resolvedType, IBinder resultTo,
2255 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002256
2257 // This is so super not safe, that only the system (or okay root)
2258 // can do it.
2259 final int callingUid = Binder.getCallingUid();
2260 if (callingUid != 0 && callingUid != Process.myUid()) {
2261 throw new SecurityException(
2262 "startActivityInPackage only available to the system");
2263 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002264
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002265 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002266 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2267 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002268 }
2269
2270 public final int startActivities(IApplicationThread caller,
2271 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2272 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2273 }
2274
2275 public final int startActivitiesInPackage(int uid,
2276 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2277
2278 // This is so super not safe, that only the system (or okay root)
2279 // can do it.
2280 final int callingUid = Binder.getCallingUid();
2281 if (callingUid != 0 && callingUid != Process.myUid()) {
2282 throw new SecurityException(
2283 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 }
2285
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002286 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002287 }
2288
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002289 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002291 // Quick case: check if the top-most recent task is the same.
2292 if (N > 0 && mRecentTasks.get(0) == task) {
2293 return;
2294 }
2295 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296 for (int i=0; i<N; i++) {
2297 TaskRecord tr = mRecentTasks.get(i);
2298 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2299 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2300 mRecentTasks.remove(i);
2301 i--;
2302 N--;
2303 if (task.intent == null) {
2304 // If the new recent task we are adding is not fully
2305 // specified, then replace it with the existing recent task.
2306 task = tr;
2307 }
2308 }
2309 }
2310 if (N >= MAX_RECENT_TASKS) {
2311 mRecentTasks.remove(N-1);
2312 }
2313 mRecentTasks.add(0, task);
2314 }
2315
2316 public void setRequestedOrientation(IBinder token,
2317 int requestedOrientation) {
2318 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002319 ActivityRecord r = mMainStack.isInStackLocked(token);
2320 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 return;
2322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 final long origId = Binder.clearCallingIdentity();
2324 mWindowManager.setAppOrientation(r, requestedOrientation);
2325 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002326 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002327 r.mayFreezeScreenLocked(r.app) ? r : null);
2328 if (config != null) {
2329 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002330 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002331 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002332 }
2333 }
2334 Binder.restoreCallingIdentity(origId);
2335 }
2336 }
2337
2338 public int getRequestedOrientation(IBinder token) {
2339 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002340 ActivityRecord r = mMainStack.isInStackLocked(token);
2341 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002342 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002344 return mWindowManager.getAppOrientation(r);
2345 }
2346 }
2347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 /**
2349 * This is the internal entry point for handling Activity.finish().
2350 *
2351 * @param token The Binder token referencing the Activity we want to finish.
2352 * @param resultCode Result code, if any, from this Activity.
2353 * @param resultData Result data (Intent), if any, from this Activity.
2354 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002355 * @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 -08002356 */
2357 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2358 // Refuse possible leaked file descriptors
2359 if (resultData != null && resultData.hasFileDescriptors() == true) {
2360 throw new IllegalArgumentException("File descriptors passed in Intent");
2361 }
2362
2363 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002364 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002365 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002366 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 if (next != null) {
2368 // ask watcher if this is allowed
2369 boolean resumeOK = true;
2370 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002371 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002372 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002373 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002374 }
2375
2376 if (!resumeOK) {
2377 return false;
2378 }
2379 }
2380 }
2381 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002382 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002383 resultData, "app-request");
2384 Binder.restoreCallingIdentity(origId);
2385 return res;
2386 }
2387 }
2388
Dianne Hackborn860755f2010-06-03 18:47:52 -07002389 public final void finishHeavyWeightApp() {
2390 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2391 != PackageManager.PERMISSION_GRANTED) {
2392 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2393 + Binder.getCallingPid()
2394 + ", uid=" + Binder.getCallingUid()
2395 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2396 Slog.w(TAG, msg);
2397 throw new SecurityException(msg);
2398 }
2399
2400 synchronized(this) {
2401 if (mHeavyWeightProcess == null) {
2402 return;
2403 }
2404
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002405 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002406 mHeavyWeightProcess.activities);
2407 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002408 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002409 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002410 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002411 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002412 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002413 null, "finish-heavy");
2414 }
2415 }
2416 }
2417
2418 mHeavyWeightProcess = null;
2419 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2420 }
2421 }
2422
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002423 public void crashApplication(int uid, int initialPid, String packageName,
2424 String message) {
2425 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2426 != PackageManager.PERMISSION_GRANTED) {
2427 String msg = "Permission Denial: crashApplication() from pid="
2428 + Binder.getCallingPid()
2429 + ", uid=" + Binder.getCallingUid()
2430 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2431 Slog.w(TAG, msg);
2432 throw new SecurityException(msg);
2433 }
2434
2435 synchronized(this) {
2436 ProcessRecord proc = null;
2437
2438 // Figure out which process to kill. We don't trust that initialPid
2439 // still has any relation to current pids, so must scan through the
2440 // list.
2441 synchronized (mPidsSelfLocked) {
2442 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2443 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2444 if (p.info.uid != uid) {
2445 continue;
2446 }
2447 if (p.pid == initialPid) {
2448 proc = p;
2449 break;
2450 }
2451 for (String str : p.pkgList) {
2452 if (str.equals(packageName)) {
2453 proc = p;
2454 }
2455 }
2456 }
2457 }
2458
2459 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002460 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002461 + " initialPid=" + initialPid
2462 + " packageName=" + packageName);
2463 return;
2464 }
2465
2466 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002467 if (proc.pid == Process.myPid()) {
2468 Log.w(TAG, "crashApplication: trying to crash self!");
2469 return;
2470 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002471 long ident = Binder.clearCallingIdentity();
2472 try {
2473 proc.thread.scheduleCrash(message);
2474 } catch (RemoteException e) {
2475 }
2476 Binder.restoreCallingIdentity(ident);
2477 }
2478 }
2479 }
2480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002481 public final void finishSubActivity(IBinder token, String resultWho,
2482 int requestCode) {
2483 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002484 ActivityRecord self = mMainStack.isInStackLocked(token);
2485 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486 return;
2487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002488
2489 final long origId = Binder.clearCallingIdentity();
2490
2491 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002492 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2493 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 if (r.resultTo == self && r.requestCode == requestCode) {
2495 if ((r.resultWho == null && resultWho == null) ||
2496 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002497 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 Activity.RESULT_CANCELED, null, "request-sub");
2499 }
2500 }
2501 }
2502
2503 Binder.restoreCallingIdentity(origId);
2504 }
2505 }
2506
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002507 public boolean willActivityBeVisible(IBinder token) {
2508 synchronized(this) {
2509 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002510 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2511 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002512 if (r == token) {
2513 return true;
2514 }
2515 if (r.fullscreen && !r.finishing) {
2516 return false;
2517 }
2518 }
2519 return true;
2520 }
2521 }
2522
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002523 public void overridePendingTransition(IBinder token, String packageName,
2524 int enterAnim, int exitAnim) {
2525 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002526 ActivityRecord self = mMainStack.isInStackLocked(token);
2527 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002528 return;
2529 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002530
2531 final long origId = Binder.clearCallingIdentity();
2532
2533 if (self.state == ActivityState.RESUMED
2534 || self.state == ActivityState.PAUSING) {
2535 mWindowManager.overridePendingAppTransition(packageName,
2536 enterAnim, exitAnim);
2537 }
2538
2539 Binder.restoreCallingIdentity(origId);
2540 }
2541 }
2542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002543 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 * Main function for removing an existing process from the activity manager
2545 * as a result of that process going away. Clears out all connections
2546 * to the process.
2547 */
2548 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002549 boolean restarting, boolean allowRestart) {
2550 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002551 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002552 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002553 }
2554
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002555 if (mProfileProc == app) {
2556 clearProfilerLocked();
2557 }
2558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002559 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002560 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2561 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2562 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002563 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002564 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2565 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002566 }
2567
2568 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002569 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002570
2571 boolean atTop = true;
2572 boolean hasVisibleActivities = false;
2573
2574 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002575 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002576 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002577 TAG, "Removing app " + app + " from history with " + i + " entries");
2578 while (i > 0) {
2579 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002580 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002581 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002582 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2583 if (r.app == app) {
2584 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002585 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002586 TAG, "Removing this entry! frozen=" + r.haveState
2587 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002588 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002589 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002590 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 mWindowManager.removeAppToken(r);
2592 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002593 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002594 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002595 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002596
2597 } else {
2598 // We have the current state for this activity, so
2599 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002600 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002601 TAG, "Keeping entry, setting app to null");
2602 if (r.visible) {
2603 hasVisibleActivities = true;
2604 }
2605 r.app = null;
2606 r.nowVisible = false;
2607 if (!r.haveState) {
2608 r.icicle = null;
2609 }
2610 }
2611
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002612 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 }
2614 atTop = false;
2615 }
2616
2617 app.activities.clear();
2618
2619 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002620 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 + " running instrumentation " + app.instrumentationClass);
2622 Bundle info = new Bundle();
2623 info.putString("shortMsg", "Process crashed.");
2624 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2625 }
2626
2627 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002628 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002629 // If there was nothing to resume, and we are not already
2630 // restarting this process, but there is a visible activity that
2631 // is hosted by the process... then make sure all visible
2632 // activities are running, taking care of restarting this
2633 // process.
2634 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002635 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002636 }
2637 }
2638 }
2639 }
2640
2641 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2642 IBinder threadBinder = thread.asBinder();
2643
2644 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002645 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2646 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2648 return i;
2649 }
2650 }
2651 return -1;
2652 }
2653
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002654 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002655 IApplicationThread thread) {
2656 if (thread == null) {
2657 return null;
2658 }
2659
2660 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002661 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002662 }
2663
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002664 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002665 IApplicationThread thread) {
2666
2667 mProcDeaths[0]++;
2668
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002669 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2670 synchronized (stats) {
2671 stats.noteProcessDiedLocked(app.info.uid, pid);
2672 }
2673
Magnus Edlund7bb25812010-02-24 15:45:06 +01002674 // Clean up already done if the process has been re-started.
2675 if (app.pid == pid && app.thread != null &&
2676 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002677 if (!app.killedBackground) {
2678 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2679 + ") has died.");
2680 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002681 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002682 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002683 TAG, "Dying app: " + app + ", pid: " + pid
2684 + ", thread: " + thread.asBinder());
2685 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002686 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002687
2688 if (doLowMem) {
2689 // If there are no longer any background processes running,
2690 // and the app that died was not running instrumentation,
2691 // then tell everyone we are now low on memory.
2692 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002693 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2694 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002695 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002696 haveBg = true;
2697 break;
2698 }
2699 }
2700
2701 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002702 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002703 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002704 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2705 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002706 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002707 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2708 // The low memory report is overriding any current
2709 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002710 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002711 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002712 rec.lastRequestedGc = 0;
2713 } else {
2714 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002715 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002716 rec.reportLowMemory = true;
2717 rec.lastLowMemory = now;
2718 mProcessesToGc.remove(rec);
2719 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002720 }
2721 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002722 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002723 }
2724 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002725 } else if (app.pid != pid) {
2726 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002727 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002728 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002729 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002730 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002731 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002732 + thread.asBinder());
2733 }
2734 }
2735
Dan Egnor42471dd2010-01-07 17:25:22 -08002736 /**
2737 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002738 * @param clearTraces causes the dump file to be erased prior to the new
2739 * traces being written, if true; when false, the new traces will be
2740 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002741 * @param firstPids of dalvik VM processes to dump stack traces for first
2742 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002743 * @return file containing stack traces, or null if no dump file is configured
2744 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002745 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2746 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002747 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2748 if (tracesPath == null || tracesPath.length() == 0) {
2749 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002750 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002751
2752 File tracesFile = new File(tracesPath);
2753 try {
2754 File tracesDir = tracesFile.getParentFile();
2755 if (!tracesDir.exists()) tracesFile.mkdirs();
2756 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2757
Christopher Tate6ee412d2010-05-28 12:01:56 -07002758 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002759 tracesFile.createNewFile();
2760 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2761 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002762 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002763 return null;
2764 }
2765
2766 // Use a FileObserver to detect when traces finish writing.
2767 // The order of traces is considered important to maintain for legibility.
2768 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2769 public synchronized void onEvent(int event, String path) { notify(); }
2770 };
2771
2772 try {
2773 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002774
2775 // First collect all of the stacks of the most important pids.
2776 try {
2777 int num = firstPids.size();
2778 for (int i = 0; i < num; i++) {
2779 synchronized (observer) {
2780 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2781 observer.wait(200); // Wait for write-close, give up after 200msec
2782 }
2783 }
2784 } catch (InterruptedException e) {
2785 Log.wtf(TAG, e);
2786 }
2787
2788 // Next measure CPU usage.
2789 if (processStats != null) {
2790 processStats.init();
2791 System.gc();
2792 processStats.update();
2793 try {
2794 synchronized (processStats) {
2795 processStats.wait(500); // measure over 1/2 second.
2796 }
2797 } catch (InterruptedException e) {
2798 }
2799 processStats.update();
2800
2801 // We'll take the stack crawls of just the top apps using CPU.
2802 final int N = processStats.countWorkingStats();
2803 int numProcs = 0;
2804 for (int i=0; i<N && numProcs<5; i++) {
2805 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2806 if (lastPids.indexOfKey(stats.pid) >= 0) {
2807 numProcs++;
2808 try {
2809 synchronized (observer) {
2810 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2811 observer.wait(200); // Wait for write-close, give up after 200msec
2812 }
2813 } catch (InterruptedException e) {
2814 Log.wtf(TAG, e);
2815 }
2816
2817 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002818 }
2819 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002820
2821 return tracesFile;
2822
Dan Egnor42471dd2010-01-07 17:25:22 -08002823 } finally {
2824 observer.stopWatching();
2825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 }
2827
Jeff Brown4d94a762010-09-23 11:33:28 -07002828 private final class AppNotResponding implements Runnable {
2829 private final ProcessRecord mApp;
2830 private final String mAnnotation;
2831
2832 public AppNotResponding(ProcessRecord app, String annotation) {
2833 mApp = app;
2834 mAnnotation = annotation;
2835 }
2836
2837 @Override
2838 public void run() {
2839 appNotResponding(mApp, null, null, mAnnotation);
2840 }
2841 }
2842
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002843 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2844 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002845 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2846 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2847
Dianne Hackborn287952c2010-09-22 22:34:31 -07002848 if (mController != null) {
2849 try {
2850 // 0 == continue, -1 = kill process immediately
2851 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2852 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2853 } catch (RemoteException e) {
2854 mController = null;
2855 }
2856 }
2857
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002858 long anrTime = SystemClock.uptimeMillis();
2859 if (MONITOR_CPU_USAGE) {
2860 updateCpuStatsNow();
2861 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002862
2863 synchronized (this) {
2864 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2865 if (mShuttingDown) {
2866 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2867 return;
2868 } else if (app.notResponding) {
2869 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2870 return;
2871 } else if (app.crashing) {
2872 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2873 return;
2874 }
2875
2876 // In case we come through here for the same app before completing
2877 // this one, mark as anring now so we will bail out.
2878 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002879
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002880 // Log the ANR to the event log.
2881 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2882 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002883
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002884 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002885 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002886
2887 int parentPid = app.pid;
2888 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002889 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002890
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002891 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002892
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002893 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2894 ProcessRecord r = mLruProcesses.get(i);
2895 if (r != null && r.thread != null) {
2896 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002897 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2898 if (r.persistent) {
2899 firstPids.add(pid);
2900 } else {
2901 lastPids.put(pid, Boolean.TRUE);
2902 }
2903 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002905 }
2906 }
2907
Dan Egnor42471dd2010-01-07 17:25:22 -08002908 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002909 StringBuilder info = mStringBuilder;
2910 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002911 info.append("ANR in ").append(app.processName);
2912 if (activity != null && activity.shortComponentName != null) {
2913 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002914 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002915 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002917 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002918 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002919 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002920 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002921 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922
Dianne Hackborn287952c2010-09-22 22:34:31 -07002923 final ProcessStats processStats = new ProcessStats(true);
2924
2925 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2926
Dan Egnor42471dd2010-01-07 17:25:22 -08002927 String cpuInfo = null;
2928 if (MONITOR_CPU_USAGE) {
2929 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002930 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002931 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002932 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002933 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002934 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 }
2936
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002937 info.append(processStats.printCurrentState(anrTime));
2938
Joe Onorato8a9b2202010-02-26 18:56:32 -08002939 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002940 if (tracesFile == null) {
2941 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2942 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2943 }
2944
2945 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2946
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002947 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002948 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002949 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2950 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002951 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002952 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2953 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002954 }
2955 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002956 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002957 }
2958 }
2959
Dan Egnor42471dd2010-01-07 17:25:22 -08002960 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2961 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2962 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002963
2964 synchronized (this) {
2965 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002966 Slog.w(TAG, "Killing " + app + ": background ANR");
2967 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
2968 app.processName, app.setAdj, "background ANR");
2969 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002970 return;
2971 }
2972
2973 // Set the app's notResponding state, and look up the errorReportReceiver
2974 makeAppNotRespondingLocked(app,
2975 activity != null ? activity.shortComponentName : null,
2976 annotation != null ? "ANR " + annotation : "ANR",
2977 info.toString());
2978
2979 // Bring up the infamous App Not Responding dialog
2980 Message msg = Message.obtain();
2981 HashMap map = new HashMap();
2982 msg.what = SHOW_NOT_RESPONDING_MSG;
2983 msg.obj = map;
2984 map.put("app", app);
2985 if (activity != null) {
2986 map.put("activity", activity);
2987 }
2988
2989 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08002990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002991 }
2992
Dianne Hackborn0dad3642010-09-09 21:25:35 -07002993 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
2994 if (!mLaunchWarningShown) {
2995 mLaunchWarningShown = true;
2996 mHandler.post(new Runnable() {
2997 @Override
2998 public void run() {
2999 synchronized (ActivityManagerService.this) {
3000 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3001 d.show();
3002 mHandler.postDelayed(new Runnable() {
3003 @Override
3004 public void run() {
3005 synchronized (ActivityManagerService.this) {
3006 d.dismiss();
3007 mLaunchWarningShown = false;
3008 }
3009 }
3010 }, 4000);
3011 }
3012 }
3013 });
3014 }
3015 }
3016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003017 public boolean clearApplicationUserData(final String packageName,
3018 final IPackageDataObserver observer) {
3019 int uid = Binder.getCallingUid();
3020 int pid = Binder.getCallingPid();
3021 long callingId = Binder.clearCallingIdentity();
3022 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003023 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003024 int pkgUid = -1;
3025 synchronized(this) {
3026 try {
3027 pkgUid = pm.getPackageUid(packageName);
3028 } catch (RemoteException e) {
3029 }
3030 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003031 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003032 return false;
3033 }
3034 if (uid == pkgUid || checkComponentPermission(
3035 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003036 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003037 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003038 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003039 } else {
3040 throw new SecurityException(pid+" does not have permission:"+
3041 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3042 "for process:"+packageName);
3043 }
3044 }
3045
3046 try {
3047 //clear application user data
3048 pm.clearApplicationUserData(packageName, observer);
3049 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3050 Uri.fromParts("package", packageName, null));
3051 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003052 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3053 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003054 } catch (RemoteException e) {
3055 }
3056 } finally {
3057 Binder.restoreCallingIdentity(callingId);
3058 }
3059 return true;
3060 }
3061
Dianne Hackborn03abb812010-01-04 18:43:19 -08003062 public void killBackgroundProcesses(final String packageName) {
3063 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3064 != PackageManager.PERMISSION_GRANTED &&
3065 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3066 != PackageManager.PERMISSION_GRANTED) {
3067 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003068 + Binder.getCallingPid()
3069 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003070 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003071 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003072 throw new SecurityException(msg);
3073 }
3074
3075 long callingId = Binder.clearCallingIdentity();
3076 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003077 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003078 int pkgUid = -1;
3079 synchronized(this) {
3080 try {
3081 pkgUid = pm.getPackageUid(packageName);
3082 } catch (RemoteException e) {
3083 }
3084 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003085 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003086 return;
3087 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003088 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn7d608422011-08-07 16:24:18 -07003089 ProcessList.SECONDARY_SERVER_ADJ, false, true, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003090 }
3091 } finally {
3092 Binder.restoreCallingIdentity(callingId);
3093 }
3094 }
3095
3096 public void forceStopPackage(final String packageName) {
3097 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3098 != PackageManager.PERMISSION_GRANTED) {
3099 String msg = "Permission Denial: forceStopPackage() from pid="
3100 + Binder.getCallingPid()
3101 + ", uid=" + Binder.getCallingUid()
3102 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003103 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003104 throw new SecurityException(msg);
3105 }
3106
3107 long callingId = Binder.clearCallingIdentity();
3108 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003109 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003110 int pkgUid = -1;
3111 synchronized(this) {
3112 try {
3113 pkgUid = pm.getPackageUid(packageName);
3114 } catch (RemoteException e) {
3115 }
3116 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003117 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003118 return;
3119 }
3120 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003121 try {
3122 pm.setPackageStoppedState(packageName, true);
3123 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003124 } catch (IllegalArgumentException e) {
3125 Slog.w(TAG, "Failed trying to unstop package "
3126 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003128 }
3129 } finally {
3130 Binder.restoreCallingIdentity(callingId);
3131 }
3132 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003133
3134 /*
3135 * The pkg name and uid have to be specified.
3136 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3137 */
3138 public void killApplicationWithUid(String pkg, int uid) {
3139 if (pkg == null) {
3140 return;
3141 }
3142 // Make sure the uid is valid.
3143 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003144 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003145 return;
3146 }
3147 int callerUid = Binder.getCallingUid();
3148 // Only the system server can kill an application
3149 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003150 // Post an aysnc message to kill the application
3151 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3152 msg.arg1 = uid;
3153 msg.arg2 = 0;
3154 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003155 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003156 } else {
3157 throw new SecurityException(callerUid + " cannot kill pkg: " +
3158 pkg);
3159 }
3160 }
3161
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003162 public void closeSystemDialogs(String reason) {
3163 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003164 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003165 if (reason != null) {
3166 intent.putExtra("reason", reason);
3167 }
3168
3169 final int uid = Binder.getCallingUid();
3170 final long origId = Binder.clearCallingIdentity();
3171 synchronized (this) {
3172 int i = mWatchers.beginBroadcast();
3173 while (i > 0) {
3174 i--;
3175 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3176 if (w != null) {
3177 try {
3178 w.closingSystemDialogs(reason);
3179 } catch (RemoteException e) {
3180 }
3181 }
3182 }
3183 mWatchers.finishBroadcast();
3184
Dianne Hackbornffa42482009-09-23 22:20:11 -07003185 mWindowManager.closeSystemDialogs(reason);
3186
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003187 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3188 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003189 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003190 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003191 Activity.RESULT_CANCELED, null, "close-sys");
3192 }
3193 }
3194
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003195 broadcastIntentLocked(null, null, intent, null,
3196 null, 0, null, null, null, false, false, -1, uid);
3197 }
3198 Binder.restoreCallingIdentity(origId);
3199 }
3200
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003201 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003202 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003203 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3204 for (int i=pids.length-1; i>=0; i--) {
3205 infos[i] = new Debug.MemoryInfo();
3206 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003207 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003208 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003209 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003210
Dianne Hackbornb437e092011-08-05 17:50:29 -07003211 public long[] getProcessPss(int[] pids) throws RemoteException {
3212 long[] pss = new long[pids.length];
3213 for (int i=pids.length-1; i>=0; i--) {
3214 pss[i] = Debug.getPss(pids[i]);
3215 }
3216 return pss;
3217 }
3218
Christopher Tate5e1ab332009-09-01 20:32:49 -07003219 public void killApplicationProcess(String processName, int uid) {
3220 if (processName == null) {
3221 return;
3222 }
3223
3224 int callerUid = Binder.getCallingUid();
3225 // Only the system server can kill an application
3226 if (callerUid == Process.SYSTEM_UID) {
3227 synchronized (this) {
3228 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003229 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003230 try {
3231 app.thread.scheduleSuicide();
3232 } catch (RemoteException e) {
3233 // If the other end already died, then our work here is done.
3234 }
3235 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003236 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003237 + processName + " / " + uid);
3238 }
3239 }
3240 } else {
3241 throw new SecurityException(callerUid + " cannot kill app process: " +
3242 processName);
3243 }
3244 }
3245
Dianne Hackborn03abb812010-01-04 18:43:19 -08003246 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003247 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003248 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3249 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003250 if (!mProcessesReady) {
3251 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003253 intent.putExtra(Intent.EXTRA_UID, uid);
3254 broadcastIntentLocked(null, null, intent,
3255 null, null, 0, null, null, null,
3256 false, false, MY_PID, Process.SYSTEM_UID);
3257 }
3258
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003259 private final boolean killPackageProcessesLocked(String packageName, int uid,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003260 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003261 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003262
Dianne Hackborn03abb812010-01-04 18:43:19 -08003263 // Remove all processes this package may have touched: all with the
3264 // same UID (except for the system or root user), and all whose name
3265 // matches the package name.
3266 final String procNamePrefix = packageName + ":";
3267 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3268 final int NA = apps.size();
3269 for (int ia=0; ia<NA; ia++) {
3270 ProcessRecord app = apps.valueAt(ia);
Christopher Tate064d8422011-07-26 15:38:07 -07003271 if (app.persistent) {
3272 // we don't kill persistent processes
3273 continue;
3274 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003275 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003276 if (doit) {
3277 procs.add(app);
3278 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003279 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3280 || app.processName.equals(packageName)
3281 || app.processName.startsWith(procNamePrefix)) {
3282 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003283 if (!doit) {
3284 return true;
3285 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003286 app.removed = true;
3287 procs.add(app);
3288 }
3289 }
3290 }
3291 }
3292
3293 int N = procs.size();
3294 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003295 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003296 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003297 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003298 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003299
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003300 private final boolean forceStopPackageLocked(String name, int uid,
3301 boolean callerWillRestart, boolean purgeCache, boolean doit) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003302 int i;
3303 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003305 if (uid < 0) {
3306 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003307 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003308 } catch (RemoteException e) {
3309 }
3310 }
3311
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003312 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003313 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003314
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003315 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3316 while (badApps.hasNext()) {
3317 SparseArray<Long> ba = badApps.next();
3318 if (ba.get(uid) != null) {
3319 badApps.remove();
3320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003321 }
3322 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003323
3324 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003325 callerWillRestart, false, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003326
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003327 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3328 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Christopher Tate064d8422011-07-26 15:38:07 -07003329 if (r.packageName.equals(name)
3330 && (r.app == null || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003331 if (!doit) {
3332 return true;
3333 }
3334 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003335 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003336 if (r.app != null) {
3337 r.app.removed = true;
3338 }
3339 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003340 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003341 }
3342 }
3343
3344 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3345 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003346 if (service.packageName.equals(name)
3347 && (service.app == null || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003348 if (!doit) {
3349 return true;
3350 }
3351 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003352 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 if (service.app != null) {
3354 service.app.removed = true;
3355 }
3356 service.app = null;
3357 services.add(service);
3358 }
3359 }
3360
3361 N = services.size();
3362 for (i=0; i<N; i++) {
3363 bringDownServiceLocked(services.get(i), true);
3364 }
3365
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003366 if (doit) {
3367 if (purgeCache) {
3368 AttributeCache ac = AttributeCache.instance();
3369 if (ac != null) {
3370 ac.removePackage(name);
3371 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003372 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003373 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003374 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003375
3376 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003377 }
3378
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003379 private final boolean removeProcessLocked(ProcessRecord app,
3380 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 final String name = app.processName;
3382 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003383 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003384 TAG, "Force removing process " + app + " (" + name
3385 + "/" + uid + ")");
3386
3387 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003388 if (mHeavyWeightProcess == app) {
3389 mHeavyWeightProcess = null;
3390 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3391 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003392 boolean needRestart = false;
3393 if (app.pid > 0 && app.pid != MY_PID) {
3394 int pid = app.pid;
3395 synchronized (mPidsSelfLocked) {
3396 mPidsSelfLocked.remove(pid);
3397 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3398 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003399 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003400 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003401 Process.killProcess(pid);
3402
3403 if (app.persistent) {
3404 if (!callerWillRestart) {
3405 addAppLocked(app.info);
3406 } else {
3407 needRestart = true;
3408 }
3409 }
3410 } else {
3411 mRemovedProcesses.add(app);
3412 }
3413
3414 return needRestart;
3415 }
3416
3417 private final void processStartTimedOutLocked(ProcessRecord app) {
3418 final int pid = app.pid;
3419 boolean gone = false;
3420 synchronized (mPidsSelfLocked) {
3421 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3422 if (knownApp != null && knownApp.thread == null) {
3423 mPidsSelfLocked.remove(pid);
3424 gone = true;
3425 }
3426 }
3427
3428 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003429 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003430 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003431 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003432 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003433 if (mHeavyWeightProcess == app) {
3434 mHeavyWeightProcess = null;
3435 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3436 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003437 // Take care of any launching providers waiting for this process.
3438 checkAppInLaunchingProvidersLocked(app, true);
3439 // Take care of any services that are waiting for the process.
3440 for (int i=0; i<mPendingServices.size(); i++) {
3441 ServiceRecord sr = mPendingServices.get(i);
3442 if (app.info.uid == sr.appInfo.uid
3443 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003444 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003445 mPendingServices.remove(i);
3446 i--;
3447 bringDownServiceLocked(sr, true);
3448 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003449 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003450 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3451 app.processName, app.setAdj, "start timeout");
3452 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003453 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003454 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003455 try {
3456 IBackupManager bm = IBackupManager.Stub.asInterface(
3457 ServiceManager.getService(Context.BACKUP_SERVICE));
3458 bm.agentDisconnected(app.info.packageName);
3459 } catch (RemoteException e) {
3460 // Can't happen; the backup manager is local
3461 }
3462 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003463 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003464 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003465 mPendingBroadcast.state = BroadcastRecord.IDLE;
3466 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003467 mPendingBroadcast = null;
3468 scheduleBroadcastsLocked();
3469 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003471 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003472 }
3473 }
3474
3475 private final boolean attachApplicationLocked(IApplicationThread thread,
3476 int pid) {
3477
3478 // Find the application record that is being attached... either via
3479 // the pid if we are running in multiple processes, or just pull the
3480 // next app record if we are emulating process with anonymous threads.
3481 ProcessRecord app;
3482 if (pid != MY_PID && pid >= 0) {
3483 synchronized (mPidsSelfLocked) {
3484 app = mPidsSelfLocked.get(pid);
3485 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003486 } else {
3487 app = null;
3488 }
3489
3490 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003491 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003492 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003493 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003494 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003495 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003496 } else {
3497 try {
3498 thread.scheduleExit();
3499 } catch (Exception e) {
3500 // Ignore exceptions.
3501 }
3502 }
3503 return false;
3504 }
3505
3506 // If this application record is still attached to a previous
3507 // process, clean it up now.
3508 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003509 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003510 }
3511
3512 // Tell the process all about itself.
3513
Joe Onorato8a9b2202010-02-26 18:56:32 -08003514 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003515 TAG, "Binding process pid " + pid + " to record " + app);
3516
3517 String processName = app.processName;
3518 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003519 AppDeathRecipient adr = new AppDeathRecipient(
3520 app, pid, thread);
3521 thread.asBinder().linkToDeath(adr, 0);
3522 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003523 } catch (RemoteException e) {
3524 app.resetPackageList();
3525 startProcessLocked(app, "link fail", processName);
3526 return false;
3527 }
3528
Doug Zongker2bec3d42009-12-04 12:52:44 -08003529 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003530
3531 app.thread = thread;
3532 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003533 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3534 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003535 app.forcingToForeground = null;
3536 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003537 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 app.debugging = false;
3539
3540 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3541
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003542 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003543 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003545 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003546 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003547 }
3548
Joe Onorato8a9b2202010-02-26 18:56:32 -08003549 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003550 TAG, "New app record " + app
3551 + " thread=" + thread.asBinder() + " pid=" + pid);
3552 try {
3553 int testMode = IApplicationThread.DEBUG_OFF;
3554 if (mDebugApp != null && mDebugApp.equals(processName)) {
3555 testMode = mWaitForDebugger
3556 ? IApplicationThread.DEBUG_WAIT
3557 : IApplicationThread.DEBUG_ON;
3558 app.debugging = true;
3559 if (mDebugTransient) {
3560 mDebugApp = mOrigDebugApp;
3561 mWaitForDebugger = mOrigWaitForDebugger;
3562 }
3563 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003564 String profileFile = app.instrumentationProfileFile;
3565 ParcelFileDescriptor profileFd = null;
3566 boolean profileAutoStop = false;
3567 if (mProfileApp != null && mProfileApp.equals(processName)) {
3568 mProfileProc = app;
3569 profileFile = mProfileFile;
3570 profileFd = mProfileFd;
3571 profileAutoStop = mAutoStopProfiler;
3572 }
3573
Christopher Tate181fafa2009-05-14 11:12:14 -07003574 // If the app is being launched for restore or full backup, set it up specially
3575 boolean isRestrictedBackupMode = false;
3576 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3577 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003578 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003579 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3580 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003581
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003582 ensurePackageDexOpt(app.instrumentationInfo != null
3583 ? app.instrumentationInfo.packageName
3584 : app.info.packageName);
3585 if (app.instrumentationClass != null) {
3586 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003587 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003588 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003589 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003590 ApplicationInfo appInfo = app.instrumentationInfo != null
3591 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003592 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003593 if (profileFd != null) {
3594 profileFd = profileFd.dup();
3595 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003596 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003597 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003599 isRestrictedBackupMode || !normalMode,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003600 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003601 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003602 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003603 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003604 } catch (Exception e) {
3605 // todo: Yikes! What should we do? For now we will try to
3606 // start another process, but that could easily get us in
3607 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003608 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003609
3610 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003611 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612 startProcessLocked(app, "bind fail", processName);
3613 return false;
3614 }
3615
3616 // Remove this record from the list of starting applications.
3617 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003618 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3619 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620 mProcessesOnHold.remove(app);
3621
3622 boolean badApp = false;
3623 boolean didSomething = false;
3624
3625 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003626 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003627 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003628 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3629 && processName.equals(hr.processName)) {
3630 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003631 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 didSomething = true;
3633 }
3634 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003635 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003636 + hr.intent.getComponent().flattenToShortString(), e);
3637 badApp = true;
3638 }
3639 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003640 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003641 }
3642 }
3643
3644 // Find any services that should be running in this process...
3645 if (!badApp && mPendingServices.size() > 0) {
3646 ServiceRecord sr = null;
3647 try {
3648 for (int i=0; i<mPendingServices.size(); i++) {
3649 sr = mPendingServices.get(i);
3650 if (app.info.uid != sr.appInfo.uid
3651 || !processName.equals(sr.processName)) {
3652 continue;
3653 }
3654
3655 mPendingServices.remove(i);
3656 i--;
3657 realStartServiceLocked(sr, app);
3658 didSomething = true;
3659 }
3660 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003661 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003662 + sr.shortName, e);
3663 badApp = true;
3664 }
3665 }
3666
3667 // Check if the next broadcast receiver is in this process...
3668 BroadcastRecord br = mPendingBroadcast;
3669 if (!badApp && br != null && br.curApp == app) {
3670 try {
3671 mPendingBroadcast = null;
3672 processCurBroadcastLocked(br, app);
3673 didSomething = true;
3674 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003675 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003676 + br.curComponent.flattenToShortString(), e);
3677 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003678 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003679 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3680 br.resultExtras, br.resultAbort, true);
3681 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003682 // We need to reset the state if we fails to start the receiver.
3683 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 }
3685 }
3686
Christopher Tate181fafa2009-05-14 11:12:14 -07003687 // Check whether the next backup agent is in this process...
3688 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003689 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003690 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003691 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003692 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3693 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3694 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003695 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003696 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003697 e.printStackTrace();
3698 }
3699 }
3700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003701 if (badApp) {
3702 // todo: Also need to kill application to deal with all
3703 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003704 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 return false;
3706 }
3707
3708 if (!didSomething) {
3709 updateOomAdjLocked();
3710 }
3711
3712 return true;
3713 }
3714
3715 public final void attachApplication(IApplicationThread thread) {
3716 synchronized (this) {
3717 int callingPid = Binder.getCallingPid();
3718 final long origId = Binder.clearCallingIdentity();
3719 attachApplicationLocked(thread, callingPid);
3720 Binder.restoreCallingIdentity(origId);
3721 }
3722 }
3723
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003724 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003726 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3727 if (stopProfiling) {
3728 synchronized (this) {
3729 if (mProfileProc == r.app) {
3730 if (mProfileFd != null) {
3731 try {
3732 mProfileFd.close();
3733 } catch (IOException e) {
3734 }
3735 clearProfilerLocked();
3736 }
3737 }
3738 }
3739 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003740 Binder.restoreCallingIdentity(origId);
3741 }
3742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003743 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003744 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003745 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 mWindowManager.enableScreenAfterBoot();
3747 }
3748
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003749 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003750 IntentFilter pkgFilter = new IntentFilter();
3751 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3752 pkgFilter.addDataScheme("package");
3753 mContext.registerReceiver(new BroadcastReceiver() {
3754 @Override
3755 public void onReceive(Context context, Intent intent) {
3756 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3757 if (pkgs != null) {
3758 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003759 synchronized (ActivityManagerService.this) {
3760 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3761 setResultCode(Activity.RESULT_OK);
3762 return;
3763 }
3764 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003765 }
3766 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003767 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003768 }, pkgFilter);
3769
3770 synchronized (this) {
3771 // Ensure that any processes we had put on hold are now started
3772 // up.
3773 final int NP = mProcessesOnHold.size();
3774 if (NP > 0) {
3775 ArrayList<ProcessRecord> procs =
3776 new ArrayList<ProcessRecord>(mProcessesOnHold);
3777 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003778 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3779 + procs.get(ip));
3780 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003781 }
3782 }
3783
3784 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003785 // Start looking for apps that are abusing wake locks.
3786 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003787 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003788 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003789 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003790 broadcastIntentLocked(null, null,
3791 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3792 null, null, 0, null, null,
3793 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3794 false, false, MY_PID, Process.SYSTEM_UID);
3795 }
3796 }
3797 }
3798
3799 final void ensureBootCompleted() {
3800 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003801 boolean enableScreen;
3802 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003803 booting = mBooting;
3804 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003805 enableScreen = !mBooted;
3806 mBooted = true;
3807 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003808
3809 if (booting) {
3810 finishBooting();
3811 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003812
3813 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003814 enableScreenAfterBoot();
3815 }
3816 }
3817
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003818 public final void activityPaused(IBinder token) {
3819 final long origId = Binder.clearCallingIdentity();
3820 mMainStack.activityPaused(token, false);
3821 Binder.restoreCallingIdentity(origId);
3822 }
3823
3824 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3825 CharSequence description) {
3826 if (localLOGV) Slog.v(
3827 TAG, "Activity stopped: token=" + token);
3828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003829 // Refuse possible leaked file descriptors
3830 if (icicle != null && icicle.hasFileDescriptors()) {
3831 throw new IllegalArgumentException("File descriptors passed in Bundle");
3832 }
3833
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003834 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003835
3836 final long origId = Binder.clearCallingIdentity();
3837
3838 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003839 r = mMainStack.isInStackLocked(token);
3840 if (r != null) {
3841 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842 }
3843 }
3844
3845 if (r != null) {
3846 sendPendingThumbnail(r, null, null, null, false);
3847 }
3848
3849 trimApplications();
3850
3851 Binder.restoreCallingIdentity(origId);
3852 }
3853
3854 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003855 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003856 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003857 }
3858
3859 public String getCallingPackage(IBinder token) {
3860 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003861 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003862 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003863 }
3864 }
3865
3866 public ComponentName getCallingActivity(IBinder token) {
3867 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003868 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003869 return r != null ? r.intent.getComponent() : null;
3870 }
3871 }
3872
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003873 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003874 ActivityRecord r = mMainStack.isInStackLocked(token);
3875 if (r == null) {
3876 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003877 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003878 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879 }
3880
3881 public ComponentName getActivityClassForToken(IBinder token) {
3882 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003883 ActivityRecord r = mMainStack.isInStackLocked(token);
3884 if (r == null) {
3885 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003887 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003888 }
3889 }
3890
3891 public String getPackageForToken(IBinder token) {
3892 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003893 ActivityRecord r = mMainStack.isInStackLocked(token);
3894 if (r == null) {
3895 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003896 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003897 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003898 }
3899 }
3900
3901 public IIntentSender getIntentSender(int type,
3902 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003903 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003904 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003905 if (intents != null) {
3906 if (intents.length < 1) {
3907 throw new IllegalArgumentException("Intents array length must be >= 1");
3908 }
3909 for (int i=0; i<intents.length; i++) {
3910 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003911 if (intent != null) {
3912 if (intent.hasFileDescriptors()) {
3913 throw new IllegalArgumentException("File descriptors passed in Intent");
3914 }
3915 if (type == INTENT_SENDER_BROADCAST &&
3916 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3917 throw new IllegalArgumentException(
3918 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3919 }
3920 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003921 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003922 }
3923 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003924 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003925 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003926 }
3927 }
3928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003929 synchronized(this) {
3930 int callingUid = Binder.getCallingUid();
3931 try {
Jeff Brown10e89712011-07-08 18:52:57 -07003932 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003933 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003934 .getPackageUid(packageName);
3935 if (uid != Binder.getCallingUid()) {
3936 String msg = "Permission Denial: getIntentSender() from pid="
3937 + Binder.getCallingPid()
3938 + ", uid=" + Binder.getCallingUid()
3939 + ", (need uid=" + uid + ")"
3940 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003941 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 throw new SecurityException(msg);
3943 }
3944 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003945
3946 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003947 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 } catch (RemoteException e) {
3950 throw new SecurityException(e);
3951 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003952 }
3953 }
3954
3955 IIntentSender getIntentSenderLocked(int type,
3956 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003957 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003958 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003959 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003960 activity = mMainStack.isInStackLocked(token);
3961 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07003962 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003964 if (activity.finishing) {
3965 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003966 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003967 }
3968
3969 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3970 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3971 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3972 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3973 |PendingIntent.FLAG_UPDATE_CURRENT);
3974
3975 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3976 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003977 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003978 WeakReference<PendingIntentRecord> ref;
3979 ref = mIntentSenderRecords.get(key);
3980 PendingIntentRecord rec = ref != null ? ref.get() : null;
3981 if (rec != null) {
3982 if (!cancelCurrent) {
3983 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003984 if (rec.key.requestIntent != null) {
3985 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
3986 }
3987 if (intents != null) {
3988 intents[intents.length-1] = rec.key.requestIntent;
3989 rec.key.allIntents = intents;
3990 rec.key.allResolvedTypes = resolvedTypes;
3991 } else {
3992 rec.key.allIntents = null;
3993 rec.key.allResolvedTypes = null;
3994 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 return rec;
3997 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003998 rec.canceled = true;
3999 mIntentSenderRecords.remove(key);
4000 }
4001 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004002 return rec;
4003 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004004 rec = new PendingIntentRecord(this, key, callingUid);
4005 mIntentSenderRecords.put(key, rec.ref);
4006 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4007 if (activity.pendingResults == null) {
4008 activity.pendingResults
4009 = new HashSet<WeakReference<PendingIntentRecord>>();
4010 }
4011 activity.pendingResults.add(rec.ref);
4012 }
4013 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004014 }
4015
4016 public void cancelIntentSender(IIntentSender sender) {
4017 if (!(sender instanceof PendingIntentRecord)) {
4018 return;
4019 }
4020 synchronized(this) {
4021 PendingIntentRecord rec = (PendingIntentRecord)sender;
4022 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004023 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004024 .getPackageUid(rec.key.packageName);
4025 if (uid != Binder.getCallingUid()) {
4026 String msg = "Permission Denial: cancelIntentSender() from pid="
4027 + Binder.getCallingPid()
4028 + ", uid=" + Binder.getCallingUid()
4029 + " is not allowed to cancel packges "
4030 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004031 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004032 throw new SecurityException(msg);
4033 }
4034 } catch (RemoteException e) {
4035 throw new SecurityException(e);
4036 }
4037 cancelIntentSenderLocked(rec, true);
4038 }
4039 }
4040
4041 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4042 rec.canceled = true;
4043 mIntentSenderRecords.remove(rec.key);
4044 if (cleanActivity && rec.key.activity != null) {
4045 rec.key.activity.pendingResults.remove(rec.ref);
4046 }
4047 }
4048
4049 public String getPackageForIntentSender(IIntentSender pendingResult) {
4050 if (!(pendingResult instanceof PendingIntentRecord)) {
4051 return null;
4052 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004053 try {
4054 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4055 return res.key.packageName;
4056 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004057 }
4058 return null;
4059 }
4060
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004061 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4062 if (!(pendingResult instanceof PendingIntentRecord)) {
4063 return false;
4064 }
4065 try {
4066 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4067 if (res.key.allIntents == null) {
4068 return false;
4069 }
4070 for (int i=0; i<res.key.allIntents.length; i++) {
4071 Intent intent = res.key.allIntents[i];
4072 if (intent.getPackage() != null && intent.getComponent() != null) {
4073 return false;
4074 }
4075 }
4076 return true;
4077 } catch (ClassCastException e) {
4078 }
4079 return false;
4080 }
4081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004082 public void setProcessLimit(int max) {
4083 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4084 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004085 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004086 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004087 mProcessLimitOverride = max;
4088 }
4089 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004090 }
4091
4092 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004093 synchronized (this) {
4094 return mProcessLimitOverride;
4095 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004096 }
4097
4098 void foregroundTokenDied(ForegroundToken token) {
4099 synchronized (ActivityManagerService.this) {
4100 synchronized (mPidsSelfLocked) {
4101 ForegroundToken cur
4102 = mForegroundProcesses.get(token.pid);
4103 if (cur != token) {
4104 return;
4105 }
4106 mForegroundProcesses.remove(token.pid);
4107 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4108 if (pr == null) {
4109 return;
4110 }
4111 pr.forcingToForeground = null;
4112 pr.foregroundServices = false;
4113 }
4114 updateOomAdjLocked();
4115 }
4116 }
4117
4118 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4119 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4120 "setProcessForeground()");
4121 synchronized(this) {
4122 boolean changed = false;
4123
4124 synchronized (mPidsSelfLocked) {
4125 ProcessRecord pr = mPidsSelfLocked.get(pid);
4126 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004127 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 return;
4129 }
4130 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4131 if (oldToken != null) {
4132 oldToken.token.unlinkToDeath(oldToken, 0);
4133 mForegroundProcesses.remove(pid);
4134 pr.forcingToForeground = null;
4135 changed = true;
4136 }
4137 if (isForeground && token != null) {
4138 ForegroundToken newToken = new ForegroundToken() {
4139 public void binderDied() {
4140 foregroundTokenDied(this);
4141 }
4142 };
4143 newToken.pid = pid;
4144 newToken.token = token;
4145 try {
4146 token.linkToDeath(newToken, 0);
4147 mForegroundProcesses.put(pid, newToken);
4148 pr.forcingToForeground = token;
4149 changed = true;
4150 } catch (RemoteException e) {
4151 // If the process died while doing this, we will later
4152 // do the cleanup with the process death link.
4153 }
4154 }
4155 }
4156
4157 if (changed) {
4158 updateOomAdjLocked();
4159 }
4160 }
4161 }
4162
4163 // =========================================================
4164 // PERMISSIONS
4165 // =========================================================
4166
4167 static class PermissionController extends IPermissionController.Stub {
4168 ActivityManagerService mActivityManagerService;
4169 PermissionController(ActivityManagerService activityManagerService) {
4170 mActivityManagerService = activityManagerService;
4171 }
4172
4173 public boolean checkPermission(String permission, int pid, int uid) {
4174 return mActivityManagerService.checkPermission(permission, pid,
4175 uid) == PackageManager.PERMISSION_GRANTED;
4176 }
4177 }
4178
4179 /**
4180 * This can be called with or without the global lock held.
4181 */
4182 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004183 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004184 // We might be performing an operation on behalf of an indirect binder
4185 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4186 // client identity accordingly before proceeding.
4187 Identity tlsIdentity = sCallerIdentity.get();
4188 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004189 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004190 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4191 uid = tlsIdentity.uid;
4192 pid = tlsIdentity.pid;
4193 }
4194
4195 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004196 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 return PackageManager.PERMISSION_GRANTED;
4198 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004199 // If there is a uid that owns whatever is being accessed, it has
4200 // blanket access to it regardless of the permissions it requires.
4201 if (owningUid >= 0 && uid == owningUid) {
4202 return PackageManager.PERMISSION_GRANTED;
4203 }
4204 // If the target is not exported, then nobody else can get to it.
4205 if (!exported) {
4206 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004207 return PackageManager.PERMISSION_DENIED;
4208 }
4209 if (permission == null) {
4210 return PackageManager.PERMISSION_GRANTED;
4211 }
4212 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004213 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004214 .checkUidPermission(permission, uid);
4215 } catch (RemoteException e) {
4216 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004217 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004218 }
4219 return PackageManager.PERMISSION_DENIED;
4220 }
4221
4222 /**
4223 * As the only public entry point for permissions checking, this method
4224 * can enforce the semantic that requesting a check on a null global
4225 * permission is automatically denied. (Internally a null permission
4226 * string is used when calling {@link #checkComponentPermission} in cases
4227 * when only uid-based security is needed.)
4228 *
4229 * This can be called with or without the global lock held.
4230 */
4231 public int checkPermission(String permission, int pid, int uid) {
4232 if (permission == null) {
4233 return PackageManager.PERMISSION_DENIED;
4234 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004235 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004236 }
4237
4238 /**
4239 * Binder IPC calls go through the public entry point.
4240 * This can be called with or without the global lock held.
4241 */
4242 int checkCallingPermission(String permission) {
4243 return checkPermission(permission,
4244 Binder.getCallingPid(),
4245 Binder.getCallingUid());
4246 }
4247
4248 /**
4249 * This can be called with or without the global lock held.
4250 */
4251 void enforceCallingPermission(String permission, String func) {
4252 if (checkCallingPermission(permission)
4253 == PackageManager.PERMISSION_GRANTED) {
4254 return;
4255 }
4256
4257 String msg = "Permission Denial: " + func + " from pid="
4258 + Binder.getCallingPid()
4259 + ", uid=" + Binder.getCallingUid()
4260 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004261 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004262 throw new SecurityException(msg);
4263 }
4264
4265 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004266 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4267 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4268 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4269 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4270 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004271 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004272 // Is the component private from the target uid?
4273 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4274
4275 // Acceptable if the there is no read permission needed from the
4276 // target or the target is holding the read permission.
4277 if (!readPerm) {
4278 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004279 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004280 == PackageManager.PERMISSION_GRANTED)) {
4281 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004282 }
4283 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004284
4285 // Acceptable if the there is no write permission needed from the
4286 // target or the target is holding the read permission.
4287 if (!writePerm) {
4288 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004289 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004290 == PackageManager.PERMISSION_GRANTED)) {
4291 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004292 }
4293 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004294
4295 // Acceptable if there is a path permission matching the URI that
4296 // the target holds the permission on.
4297 PathPermission[] pps = pi.pathPermissions;
4298 if (pps != null && (!readPerm || !writePerm)) {
4299 final String path = uri.getPath();
4300 int i = pps.length;
4301 while (i > 0 && (!readPerm || !writePerm)) {
4302 i--;
4303 PathPermission pp = pps[i];
4304 if (!readPerm) {
4305 final String pprperm = pp.getReadPermission();
4306 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4307 + pprperm + " for " + pp.getPath()
4308 + ": match=" + pp.match(path)
4309 + " check=" + pm.checkUidPermission(pprperm, uid));
4310 if (pprperm != null && pp.match(path) &&
4311 (pm.checkUidPermission(pprperm, uid)
4312 == PackageManager.PERMISSION_GRANTED)) {
4313 readPerm = true;
4314 }
4315 }
4316 if (!writePerm) {
4317 final String ppwperm = pp.getWritePermission();
4318 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4319 + ppwperm + " for " + pp.getPath()
4320 + ": match=" + pp.match(path)
4321 + " check=" + pm.checkUidPermission(ppwperm, uid));
4322 if (ppwperm != null && pp.match(path) &&
4323 (pm.checkUidPermission(ppwperm, uid)
4324 == PackageManager.PERMISSION_GRANTED)) {
4325 writePerm = true;
4326 }
4327 }
4328 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004329 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004330 } catch (RemoteException e) {
4331 return false;
4332 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004333
4334 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004335 }
4336
4337 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4338 int modeFlags) {
4339 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004340 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004341 return true;
4342 }
4343 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4344 if (perms == null) return false;
4345 UriPermission perm = perms.get(uri);
4346 if (perm == null) return false;
4347 return (modeFlags&perm.modeFlags) == modeFlags;
4348 }
4349
4350 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4351 // Another redirected-binder-call permissions check as in
4352 // {@link checkComponentPermission}.
4353 Identity tlsIdentity = sCallerIdentity.get();
4354 if (tlsIdentity != null) {
4355 uid = tlsIdentity.uid;
4356 pid = tlsIdentity.pid;
4357 }
4358
4359 // Our own process gets to do everything.
4360 if (pid == MY_PID) {
4361 return PackageManager.PERMISSION_GRANTED;
4362 }
4363 synchronized(this) {
4364 return checkUriPermissionLocked(uri, uid, modeFlags)
4365 ? PackageManager.PERMISSION_GRANTED
4366 : PackageManager.PERMISSION_DENIED;
4367 }
4368 }
4369
Dianne Hackborn39792d22010-08-19 18:01:52 -07004370 /**
4371 * Check if the targetPkg can be granted permission to access uri by
4372 * the callingUid using the given modeFlags. Throws a security exception
4373 * if callingUid is not allowed to do this. Returns the uid of the target
4374 * if the URI permission grant should be performed; returns -1 if it is not
4375 * needed (for example targetPkg already has permission to access the URI).
4376 */
4377 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4378 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004379 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4380 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4381 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004382 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004383 }
4384
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004385 if (targetPkg != null) {
4386 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4387 "Checking grant " + targetPkg + " permission to " + uri);
4388 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004389
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004390 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004391
4392 // If this is not a content: uri, we can't do anything with it.
4393 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004394 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004395 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004396 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004397 }
4398
4399 String name = uri.getAuthority();
4400 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004401 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004402 if (cpr != null) {
4403 pi = cpr.info;
4404 } else {
4405 try {
4406 pi = pm.resolveContentProvider(name,
4407 PackageManager.GET_URI_PERMISSION_PATTERNS);
4408 } catch (RemoteException ex) {
4409 }
4410 }
4411 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004412 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004413 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004414 }
4415
4416 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004417 if (targetPkg != null) {
4418 try {
4419 targetUid = pm.getPackageUid(targetPkg);
4420 if (targetUid < 0) {
4421 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4422 "Can't grant URI permission no uid for: " + targetPkg);
4423 return -1;
4424 }
4425 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004426 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004427 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004428 } else {
4429 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004430 }
4431
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004432 if (targetUid >= 0) {
4433 // First... does the target actually need this permission?
4434 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4435 // No need to grant the target this permission.
4436 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4437 "Target " + targetPkg + " already has full permission to " + uri);
4438 return -1;
4439 }
4440 } else {
4441 // First... there is no target package, so can anyone access it?
4442 boolean allowed = pi.exported;
4443 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4444 if (pi.readPermission != null) {
4445 allowed = false;
4446 }
4447 }
4448 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4449 if (pi.writePermission != null) {
4450 allowed = false;
4451 }
4452 }
4453 if (allowed) {
4454 return -1;
4455 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004456 }
4457
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004458 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004459 if (!pi.grantUriPermissions) {
4460 throw new SecurityException("Provider " + pi.packageName
4461 + "/" + pi.name
4462 + " does not allow granting of Uri permissions (uri "
4463 + uri + ")");
4464 }
4465 if (pi.uriPermissionPatterns != null) {
4466 final int N = pi.uriPermissionPatterns.length;
4467 boolean allowed = false;
4468 for (int i=0; i<N; i++) {
4469 if (pi.uriPermissionPatterns[i] != null
4470 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4471 allowed = true;
4472 break;
4473 }
4474 }
4475 if (!allowed) {
4476 throw new SecurityException("Provider " + pi.packageName
4477 + "/" + pi.name
4478 + " does not allow granting of permission to path of Uri "
4479 + uri);
4480 }
4481 }
4482
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004483 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004484 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004485 if (callingUid != Process.myUid()) {
4486 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4487 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4488 throw new SecurityException("Uid " + callingUid
4489 + " does not have permission to uri " + uri);
4490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004491 }
4492 }
4493
Dianne Hackborn39792d22010-08-19 18:01:52 -07004494 return targetUid;
4495 }
4496
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004497 public int checkGrantUriPermission(int callingUid, String targetPkg,
4498 Uri uri, int modeFlags) {
4499 synchronized(this) {
4500 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4501 }
4502 }
4503
Dianne Hackborn39792d22010-08-19 18:01:52 -07004504 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4505 Uri uri, int modeFlags, UriPermissionOwner owner) {
4506 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4507 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4508 if (modeFlags == 0) {
4509 return;
4510 }
4511
4512 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004513 // to the uri, and the target doesn't. Let's now give this to
4514 // the target.
4515
Joe Onorato8a9b2202010-02-26 18:56:32 -08004516 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004517 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004519 HashMap<Uri, UriPermission> targetUris
4520 = mGrantedUriPermissions.get(targetUid);
4521 if (targetUris == null) {
4522 targetUris = new HashMap<Uri, UriPermission>();
4523 mGrantedUriPermissions.put(targetUid, targetUris);
4524 }
4525
4526 UriPermission perm = targetUris.get(uri);
4527 if (perm == null) {
4528 perm = new UriPermission(targetUid, uri);
4529 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004530 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004532 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004533 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004534 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004535 } else {
4536 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4537 perm.readOwners.add(owner);
4538 owner.addReadPermission(perm);
4539 }
4540 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4541 perm.writeOwners.add(owner);
4542 owner.addWritePermission(perm);
4543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004544 }
4545 }
4546
Dianne Hackborn39792d22010-08-19 18:01:52 -07004547 void grantUriPermissionLocked(int callingUid,
4548 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004549 if (targetPkg == null) {
4550 throw new NullPointerException("targetPkg");
4551 }
4552
Dianne Hackborn39792d22010-08-19 18:01:52 -07004553 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4554 if (targetUid < 0) {
4555 return;
4556 }
4557
4558 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4559 }
4560
4561 /**
4562 * Like checkGrantUriPermissionLocked, but takes an Intent.
4563 */
4564 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4565 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004566 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004567 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004568 + " from " + intent + "; flags=0x"
4569 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4570
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004571 if (targetPkg == null) {
4572 throw new NullPointerException("targetPkg");
4573 }
4574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004575 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004576 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004577 }
4578 Uri data = intent.getData();
4579 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004580 return -1;
4581 }
4582 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4583 intent.getFlags());
4584 }
4585
4586 /**
4587 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4588 */
4589 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4590 String targetPkg, Intent intent, UriPermissionOwner owner) {
4591 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4592 intent.getFlags(), owner);
4593 }
4594
4595 void grantUriPermissionFromIntentLocked(int callingUid,
4596 String targetPkg, Intent intent, UriPermissionOwner owner) {
4597 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4598 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004599 return;
4600 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004601
4602 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 }
4604
4605 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4606 Uri uri, int modeFlags) {
4607 synchronized(this) {
4608 final ProcessRecord r = getRecordForAppLocked(caller);
4609 if (r == null) {
4610 throw new SecurityException("Unable to find app for caller "
4611 + caller
4612 + " when granting permission to uri " + uri);
4613 }
4614 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004615 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004616 }
4617 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004618 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004619 }
4620
4621 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4622 null);
4623 }
4624 }
4625
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004626 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004627 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4628 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4629 HashMap<Uri, UriPermission> perms
4630 = mGrantedUriPermissions.get(perm.uid);
4631 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004632 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004633 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004634 perms.remove(perm.uri);
4635 if (perms.size() == 0) {
4636 mGrantedUriPermissions.remove(perm.uid);
4637 }
4638 }
4639 }
4640 }
4641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4643 int modeFlags) {
4644 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4645 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4646 if (modeFlags == 0) {
4647 return;
4648 }
4649
Joe Onorato8a9b2202010-02-26 18:56:32 -08004650 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004651 "Revoking all granted permissions to " + uri);
4652
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004653 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004654
4655 final String authority = uri.getAuthority();
4656 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004657 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004658 if (cpr != null) {
4659 pi = cpr.info;
4660 } else {
4661 try {
4662 pi = pm.resolveContentProvider(authority,
4663 PackageManager.GET_URI_PERMISSION_PATTERNS);
4664 } catch (RemoteException ex) {
4665 }
4666 }
4667 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004668 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004669 return;
4670 }
4671
4672 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004673 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004674 // Right now, if you are not the original owner of the permission,
4675 // you are not allowed to revoke it.
4676 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4677 throw new SecurityException("Uid " + callingUid
4678 + " does not have permission to uri " + uri);
4679 //}
4680 }
4681
4682 // Go through all of the permissions and remove any that match.
4683 final List<String> SEGMENTS = uri.getPathSegments();
4684 if (SEGMENTS != null) {
4685 final int NS = SEGMENTS.size();
4686 int N = mGrantedUriPermissions.size();
4687 for (int i=0; i<N; i++) {
4688 HashMap<Uri, UriPermission> perms
4689 = mGrantedUriPermissions.valueAt(i);
4690 Iterator<UriPermission> it = perms.values().iterator();
4691 toploop:
4692 while (it.hasNext()) {
4693 UriPermission perm = it.next();
4694 Uri targetUri = perm.uri;
4695 if (!authority.equals(targetUri.getAuthority())) {
4696 continue;
4697 }
4698 List<String> targetSegments = targetUri.getPathSegments();
4699 if (targetSegments == null) {
4700 continue;
4701 }
4702 if (targetSegments.size() < NS) {
4703 continue;
4704 }
4705 for (int j=0; j<NS; j++) {
4706 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4707 continue toploop;
4708 }
4709 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004710 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004711 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004712 perm.clearModes(modeFlags);
4713 if (perm.modeFlags == 0) {
4714 it.remove();
4715 }
4716 }
4717 if (perms.size() == 0) {
4718 mGrantedUriPermissions.remove(
4719 mGrantedUriPermissions.keyAt(i));
4720 N--;
4721 i--;
4722 }
4723 }
4724 }
4725 }
4726
4727 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4728 int modeFlags) {
4729 synchronized(this) {
4730 final ProcessRecord r = getRecordForAppLocked(caller);
4731 if (r == null) {
4732 throw new SecurityException("Unable to find app for caller "
4733 + caller
4734 + " when revoking permission to uri " + uri);
4735 }
4736 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004737 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004738 return;
4739 }
4740
4741 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4742 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4743 if (modeFlags == 0) {
4744 return;
4745 }
4746
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004747 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004748
4749 final String authority = uri.getAuthority();
4750 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004751 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004752 if (cpr != null) {
4753 pi = cpr.info;
4754 } else {
4755 try {
4756 pi = pm.resolveContentProvider(authority,
4757 PackageManager.GET_URI_PERMISSION_PATTERNS);
4758 } catch (RemoteException ex) {
4759 }
4760 }
4761 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004762 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004763 return;
4764 }
4765
4766 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4767 }
4768 }
4769
Dianne Hackborn7e269642010-08-25 19:50:20 -07004770 @Override
4771 public IBinder newUriPermissionOwner(String name) {
4772 synchronized(this) {
4773 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4774 return owner.getExternalTokenLocked();
4775 }
4776 }
4777
4778 @Override
4779 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4780 Uri uri, int modeFlags) {
4781 synchronized(this) {
4782 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4783 if (owner == null) {
4784 throw new IllegalArgumentException("Unknown owner: " + token);
4785 }
4786 if (fromUid != Binder.getCallingUid()) {
4787 if (Binder.getCallingUid() != Process.myUid()) {
4788 // Only system code can grant URI permissions on behalf
4789 // of other users.
4790 throw new SecurityException("nice try");
4791 }
4792 }
4793 if (targetPkg == null) {
4794 throw new IllegalArgumentException("null target");
4795 }
4796 if (uri == null) {
4797 throw new IllegalArgumentException("null uri");
4798 }
4799
4800 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4801 }
4802 }
4803
4804 @Override
4805 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4806 synchronized(this) {
4807 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4808 if (owner == null) {
4809 throw new IllegalArgumentException("Unknown owner: " + token);
4810 }
4811
4812 if (uri == null) {
4813 owner.removeUriPermissionsLocked(mode);
4814 } else {
4815 owner.removeUriPermissionLocked(uri, mode);
4816 }
4817 }
4818 }
4819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004820 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4821 synchronized (this) {
4822 ProcessRecord app =
4823 who != null ? getRecordForAppLocked(who) : null;
4824 if (app == null) return;
4825
4826 Message msg = Message.obtain();
4827 msg.what = WAIT_FOR_DEBUGGER_MSG;
4828 msg.obj = app;
4829 msg.arg1 = waiting ? 1 : 0;
4830 mHandler.sendMessage(msg);
4831 }
4832 }
4833
4834 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004835 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4836 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004837 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004838 outInfo.threshold = homeAppMem;
4839 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4840 outInfo.hiddenAppThreshold = hiddenAppMem;
4841 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4842 ProcessList.SECONDARY_SERVER_ADJ);
4843 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4844 ProcessList.VISIBLE_APP_ADJ);
4845 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4846 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004847 }
4848
4849 // =========================================================
4850 // TASK MANAGEMENT
4851 // =========================================================
4852
4853 public List getTasks(int maxNum, int flags,
4854 IThumbnailReceiver receiver) {
4855 ArrayList list = new ArrayList();
4856
4857 PendingThumbnailsRecord pending = null;
4858 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004859 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004860
4861 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004862 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004863 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4864 + ", receiver=" + receiver);
4865
4866 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4867 != PackageManager.PERMISSION_GRANTED) {
4868 if (receiver != null) {
4869 // If the caller wants to wait for pending thumbnails,
4870 // it ain't gonna get them.
4871 try {
4872 receiver.finished();
4873 } catch (RemoteException ex) {
4874 }
4875 }
4876 String msg = "Permission Denial: getTasks() from pid="
4877 + Binder.getCallingPid()
4878 + ", uid=" + Binder.getCallingUid()
4879 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004880 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004881 throw new SecurityException(msg);
4882 }
4883
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004884 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004885 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004886 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004887 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004888 TaskRecord curTask = null;
4889 int numActivities = 0;
4890 int numRunning = 0;
4891 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004892 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004893 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004894 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004895
4896 // Initialize state for next task if needed.
4897 if (top == null ||
4898 (top.state == ActivityState.INITIALIZING
4899 && top.task == r.task)) {
4900 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004901 curTask = r.task;
4902 numActivities = numRunning = 0;
4903 }
4904
4905 // Add 'r' into the current task.
4906 numActivities++;
4907 if (r.app != null && r.app.thread != null) {
4908 numRunning++;
4909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004910
Joe Onorato8a9b2202010-02-26 18:56:32 -08004911 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004912 TAG, r.intent.getComponent().flattenToShortString()
4913 + ": task=" + r.task);
4914
4915 // If the next one is a different task, generate a new
4916 // TaskInfo entry for what we have.
4917 if (next == null || next.task != curTask) {
4918 ActivityManager.RunningTaskInfo ci
4919 = new ActivityManager.RunningTaskInfo();
4920 ci.id = curTask.taskId;
4921 ci.baseActivity = r.intent.getComponent();
4922 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004923 if (top.thumbHolder != null) {
4924 ci.description = top.thumbHolder.lastDescription;
4925 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004926 ci.numActivities = numActivities;
4927 ci.numRunning = numRunning;
4928 //System.out.println(
4929 // "#" + maxNum + ": " + " descr=" + ci.description);
4930 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004931 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004932 TAG, "State=" + top.state + "Idle=" + top.idle
4933 + " app=" + top.app
4934 + " thr=" + (top.app != null ? top.app.thread : null));
4935 if (top.state == ActivityState.RESUMED
4936 || top.state == ActivityState.PAUSING) {
4937 if (top.idle && top.app != null
4938 && top.app.thread != null) {
4939 topRecord = top;
4940 topThumbnail = top.app.thread;
4941 } else {
4942 top.thumbnailNeeded = true;
4943 }
4944 }
4945 if (pending == null) {
4946 pending = new PendingThumbnailsRecord(receiver);
4947 }
4948 pending.pendingRecords.add(top);
4949 }
4950 list.add(ci);
4951 maxNum--;
4952 top = null;
4953 }
4954 }
4955
4956 if (pending != null) {
4957 mPendingThumbnails.add(pending);
4958 }
4959 }
4960
Joe Onorato8a9b2202010-02-26 18:56:32 -08004961 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962
4963 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004964 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004965 try {
4966 topThumbnail.requestThumbnail(topRecord);
4967 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004968 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 sendPendingThumbnail(null, topRecord, null, null, true);
4970 }
4971 }
4972
4973 if (pending == null && receiver != null) {
4974 // In this case all thumbnails were available and the client
4975 // is being asked to be told when the remaining ones come in...
4976 // which is unusually, since the top-most currently running
4977 // activity should never have a canned thumbnail! Oh well.
4978 try {
4979 receiver.finished();
4980 } catch (RemoteException ex) {
4981 }
4982 }
4983
4984 return list;
4985 }
4986
4987 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4988 int flags) {
4989 synchronized (this) {
4990 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4991 "getRecentTasks()");
4992
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004993 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07004994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004995 final int N = mRecentTasks.size();
4996 ArrayList<ActivityManager.RecentTaskInfo> res
4997 = new ArrayList<ActivityManager.RecentTaskInfo>(
4998 maxNum < N ? maxNum : N);
4999 for (int i=0; i<N && maxNum > 0; i++) {
5000 TaskRecord tr = mRecentTasks.get(i);
5001 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5002 || (tr.intent == null)
5003 || ((tr.intent.getFlags()
5004 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5005 ActivityManager.RecentTaskInfo rti
5006 = new ActivityManager.RecentTaskInfo();
5007 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005008 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005009 rti.baseIntent = new Intent(
5010 tr.intent != null ? tr.intent : tr.affinityIntent);
5011 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005012 rti.description = tr.lastDescription;
5013
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005014 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5015 // Check whether this activity is currently available.
5016 try {
5017 if (rti.origActivity != null) {
5018 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5019 continue;
5020 }
5021 } else if (rti.baseIntent != null) {
5022 if (pm.queryIntentActivities(rti.baseIntent,
5023 null, 0) == null) {
5024 continue;
5025 }
5026 }
5027 } catch (RemoteException e) {
5028 // Will never happen.
5029 }
5030 }
5031
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005032 res.add(rti);
5033 maxNum--;
5034 }
5035 }
5036 return res;
5037 }
5038 }
5039
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005040 private TaskRecord taskForIdLocked(int id) {
5041 final int N = mRecentTasks.size();
5042 for (int i=0; i<N; i++) {
5043 TaskRecord tr = mRecentTasks.get(i);
5044 if (tr.taskId == id) {
5045 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005046 }
5047 }
5048 return null;
5049 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005050
5051 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5052 synchronized (this) {
5053 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5054 "getTaskThumbnails()");
5055 TaskRecord tr = taskForIdLocked(id);
5056 if (tr != null) {
5057 return mMainStack.getTaskThumbnailsLocked(tr);
5058 }
5059 }
5060 return null;
5061 }
5062
5063 public boolean removeSubTask(int taskId, int subTaskIndex) {
5064 synchronized (this) {
5065 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5066 "removeSubTask()");
5067 long ident = Binder.clearCallingIdentity();
5068 try {
5069 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5070 } finally {
5071 Binder.restoreCallingIdentity(ident);
5072 }
5073 }
5074 }
5075
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005076 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005077 TaskRecord tr = root.task;
5078 Intent baseIntent = new Intent(
5079 tr.intent != null ? tr.intent : tr.affinityIntent);
5080 ComponentName component = baseIntent.getComponent();
5081 if (component == null) {
5082 Slog.w(TAG, "Now component for base intent of task: " + tr);
5083 return;
5084 }
5085
5086 // Find any running services associated with this app.
5087 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5088 for (ServiceRecord sr : mServices.values()) {
5089 if (sr.packageName.equals(component.getPackageName())) {
5090 services.add(sr);
5091 }
5092 }
5093
5094 // Take care of any running services associated with the app.
5095 for (int i=0; i<services.size(); i++) {
5096 ServiceRecord sr = services.get(i);
5097 if (sr.startRequested) {
5098 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005099 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005100 stopServiceLocked(sr);
5101 } else {
5102 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5103 sr.makeNextStartId(), baseIntent, -1));
5104 if (sr.app != null && sr.app.thread != null) {
5105 sendServiceArgsLocked(sr, false);
5106 }
5107 }
5108 }
5109 }
5110
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005111 if (killProcesses) {
5112 // Find any running processes associated with this app.
5113 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5114 SparseArray<ProcessRecord> appProcs
5115 = mProcessNames.getMap().get(component.getPackageName());
5116 if (appProcs != null) {
5117 for (int i=0; i<appProcs.size(); i++) {
5118 procs.add(appProcs.valueAt(i));
5119 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005120 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005121
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005122 // Kill the running processes.
5123 for (int i=0; i<procs.size(); i++) {
5124 ProcessRecord pr = procs.get(i);
5125 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5126 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5127 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5128 pr.processName, pr.setAdj, "remove task");
5129 Process.killProcessQuiet(pr.pid);
5130 } else {
5131 pr.waitingToKill = "remove task";
5132 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005133 }
5134 }
5135 }
5136
5137 public boolean removeTask(int taskId, int flags) {
5138 synchronized (this) {
5139 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5140 "removeTask()");
5141 long ident = Binder.clearCallingIdentity();
5142 try {
5143 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5144 if (r != null) {
5145 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005146 cleanUpRemovedTaskLocked(r,
5147 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005148 return true;
5149 }
5150 } finally {
5151 Binder.restoreCallingIdentity(ident);
5152 }
5153 }
5154 return false;
5155 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005157 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5158 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005159 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005160 TaskRecord jt = startTask;
5161
5162 // First look backwards
5163 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005164 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005165 if (r.task != jt) {
5166 jt = r.task;
5167 if (affinity.equals(jt.affinity)) {
5168 return j;
5169 }
5170 }
5171 }
5172
5173 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005174 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005175 jt = startTask;
5176 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005177 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005178 if (r.task != jt) {
5179 if (affinity.equals(jt.affinity)) {
5180 return j;
5181 }
5182 jt = r.task;
5183 }
5184 }
5185
5186 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005187 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005188 return N-1;
5189 }
5190
5191 return -1;
5192 }
5193
5194 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005195 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005196 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005197 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005198 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5199 "moveTaskToFront()");
5200
5201 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005202 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5203 Binder.getCallingUid(), "Task to front")) {
5204 return;
5205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005206 final long origId = Binder.clearCallingIdentity();
5207 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005208 TaskRecord tr = taskForIdLocked(task);
5209 if (tr != null) {
5210 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5211 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005212 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005213 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5214 // Caller wants the home activity moved with it. To accomplish this,
5215 // we'll just move the home task to the top first.
5216 mMainStack.moveHomeToFrontLocked();
5217 }
5218 mMainStack.moveTaskToFrontLocked(tr, null);
5219 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005220 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005221 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5222 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005223 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005224 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5225 mMainStack.mUserLeaving = true;
5226 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005227 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5228 // Caller wants the home activity moved with it. To accomplish this,
5229 // we'll just move the home task to the top first.
5230 mMainStack.moveHomeToFrontLocked();
5231 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005232 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005233 return;
5234 }
5235 }
5236 } finally {
5237 Binder.restoreCallingIdentity(origId);
5238 }
5239 }
5240 }
5241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005242 public void moveTaskToBack(int task) {
5243 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5244 "moveTaskToBack()");
5245
5246 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005247 if (mMainStack.mResumedActivity != null
5248 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005249 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5250 Binder.getCallingUid(), "Task to back")) {
5251 return;
5252 }
5253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005254 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005255 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005256 Binder.restoreCallingIdentity(origId);
5257 }
5258 }
5259
5260 /**
5261 * Moves an activity, and all of the other activities within the same task, to the bottom
5262 * of the history stack. The activity's order within the task is unchanged.
5263 *
5264 * @param token A reference to the activity we wish to move
5265 * @param nonRoot If false then this only works if the activity is the root
5266 * of a task; if true it will work for any activity in a task.
5267 * @return Returns true if the move completed, false if not.
5268 */
5269 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5270 synchronized(this) {
5271 final long origId = Binder.clearCallingIdentity();
5272 int taskId = getTaskForActivityLocked(token, !nonRoot);
5273 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005274 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005275 }
5276 Binder.restoreCallingIdentity(origId);
5277 }
5278 return false;
5279 }
5280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005281 public void moveTaskBackwards(int task) {
5282 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5283 "moveTaskBackwards()");
5284
5285 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005286 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5287 Binder.getCallingUid(), "Task backwards")) {
5288 return;
5289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005290 final long origId = Binder.clearCallingIdentity();
5291 moveTaskBackwardsLocked(task);
5292 Binder.restoreCallingIdentity(origId);
5293 }
5294 }
5295
5296 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005297 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005298 }
5299
5300 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5301 synchronized(this) {
5302 return getTaskForActivityLocked(token, onlyRoot);
5303 }
5304 }
5305
5306 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005307 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005308 TaskRecord lastTask = null;
5309 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005310 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005311 if (r == token) {
5312 if (!onlyRoot || lastTask != r.task) {
5313 return r.task.taskId;
5314 }
5315 return -1;
5316 }
5317 lastTask = r.task;
5318 }
5319
5320 return -1;
5321 }
5322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005323 public void finishOtherInstances(IBinder token, ComponentName className) {
5324 synchronized(this) {
5325 final long origId = Binder.clearCallingIdentity();
5326
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005327 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005328 TaskRecord lastTask = null;
5329 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005330 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005331 if (r.realActivity.equals(className)
5332 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005333 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005334 null, "others")) {
5335 i--;
5336 N--;
5337 }
5338 }
5339 lastTask = r.task;
5340 }
5341
5342 Binder.restoreCallingIdentity(origId);
5343 }
5344 }
5345
5346 // =========================================================
5347 // THUMBNAILS
5348 // =========================================================
5349
5350 public void reportThumbnail(IBinder token,
5351 Bitmap thumbnail, CharSequence description) {
5352 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5353 final long origId = Binder.clearCallingIdentity();
5354 sendPendingThumbnail(null, token, thumbnail, description, true);
5355 Binder.restoreCallingIdentity(origId);
5356 }
5357
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005358 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005359 Bitmap thumbnail, CharSequence description, boolean always) {
5360 TaskRecord task = null;
5361 ArrayList receivers = null;
5362
5363 //System.out.println("Send pending thumbnail: " + r);
5364
5365 synchronized(this) {
5366 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005367 r = mMainStack.isInStackLocked(token);
5368 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005369 return;
5370 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005371 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005372 if (thumbnail == null && r.thumbHolder != null) {
5373 thumbnail = r.thumbHolder.lastThumbnail;
5374 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005375 }
5376 if (thumbnail == null && !always) {
5377 // If there is no thumbnail, and this entry is not actually
5378 // going away, then abort for now and pick up the next
5379 // thumbnail we get.
5380 return;
5381 }
5382 task = r.task;
5383
5384 int N = mPendingThumbnails.size();
5385 int i=0;
5386 while (i<N) {
5387 PendingThumbnailsRecord pr =
5388 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5389 //System.out.println("Looking in " + pr.pendingRecords);
5390 if (pr.pendingRecords.remove(r)) {
5391 if (receivers == null) {
5392 receivers = new ArrayList();
5393 }
5394 receivers.add(pr);
5395 if (pr.pendingRecords.size() == 0) {
5396 pr.finished = true;
5397 mPendingThumbnails.remove(i);
5398 N--;
5399 continue;
5400 }
5401 }
5402 i++;
5403 }
5404 }
5405
5406 if (receivers != null) {
5407 final int N = receivers.size();
5408 for (int i=0; i<N; i++) {
5409 try {
5410 PendingThumbnailsRecord pr =
5411 (PendingThumbnailsRecord)receivers.get(i);
5412 pr.receiver.newThumbnail(
5413 task != null ? task.taskId : -1, thumbnail, description);
5414 if (pr.finished) {
5415 pr.receiver.finished();
5416 }
5417 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005418 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005419 }
5420 }
5421 }
5422 }
5423
5424 // =========================================================
5425 // CONTENT PROVIDERS
5426 // =========================================================
5427
Jeff Brown10e89712011-07-08 18:52:57 -07005428 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5429 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005430 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005431 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005433 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005434 } catch (RemoteException ex) {
5435 }
5436 if (providers != null) {
5437 final int N = providers.size();
5438 for (int i=0; i<N; i++) {
5439 ProviderInfo cpi =
5440 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005441 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5442 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005443 if (cpr == null) {
5444 cpr = new ContentProviderRecord(cpi, app.info);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005445 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 }
5447 app.pubProviders.put(cpi.name, cpr);
5448 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005449 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005450 }
5451 }
5452 return providers;
5453 }
5454
5455 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005456 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005457 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5458 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5459 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005460 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005461 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005462 return null;
5463 }
5464 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005465 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 == PackageManager.PERMISSION_GRANTED) {
5467 return null;
5468 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005469
5470 PathPermission[] pps = cpi.pathPermissions;
5471 if (pps != null) {
5472 int i = pps.length;
5473 while (i > 0) {
5474 i--;
5475 PathPermission pp = pps[i];
5476 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005477 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005478 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005479 return null;
5480 }
5481 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005482 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005483 == PackageManager.PERMISSION_GRANTED) {
5484 return null;
5485 }
5486 }
5487 }
5488
Dianne Hackbornb424b632010-08-18 15:59:05 -07005489 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5490 if (perms != null) {
5491 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5492 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5493 return null;
5494 }
5495 }
5496 }
5497
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005498 String msg;
5499 if (!cpi.exported) {
5500 msg = "Permission Denial: opening provider " + cpi.name
5501 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5502 + ", uid=" + callingUid + ") that is not exported from uid "
5503 + cpi.applicationInfo.uid;
5504 } else {
5505 msg = "Permission Denial: opening provider " + cpi.name
5506 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5507 + ", uid=" + callingUid + ") requires "
5508 + cpi.readPermission + " or " + cpi.writePermission;
5509 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005510 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005511 return msg;
5512 }
5513
5514 private final ContentProviderHolder getContentProviderImpl(
5515 IApplicationThread caller, String name) {
5516 ContentProviderRecord cpr;
5517 ProviderInfo cpi = null;
5518
5519 synchronized(this) {
5520 ProcessRecord r = null;
5521 if (caller != null) {
5522 r = getRecordForAppLocked(caller);
5523 if (r == null) {
5524 throw new SecurityException(
5525 "Unable to find app for caller " + caller
5526 + " (pid=" + Binder.getCallingPid()
5527 + ") when getting content provider " + name);
5528 }
5529 }
5530
5531 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005532 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005533 if (cpr != null) {
5534 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005535 String msg;
5536 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5537 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005538 }
5539
5540 if (r != null && cpr.canRunHere(r)) {
5541 // This provider has been published or is in the process
5542 // of being published... but it is also allowed to run
5543 // in the caller's process, so don't make a connection
5544 // and just let the caller instantiate its own instance.
5545 if (cpr.provider != null) {
5546 // don't give caller the provider object, it needs
5547 // to make its own.
5548 cpr = new ContentProviderRecord(cpr);
5549 }
5550 return cpr;
5551 }
5552
5553 final long origId = Binder.clearCallingIdentity();
5554
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005555 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005556 // return it right away.
5557 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005558 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005559 "Adding provider requested by "
5560 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005561 + cpr.info.processName);
5562 Integer cnt = r.conProviders.get(cpr);
5563 if (cnt == null) {
5564 r.conProviders.put(cpr, new Integer(1));
5565 } else {
5566 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005568 cpr.clients.add(r);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005569 if (cpr.app != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005570 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005571 // make sure to count it as being accessed and thus
5572 // back up on the LRU list. This is good because
5573 // content providers are often expensive to start.
5574 updateLruProcessLocked(cpr.app, false, true);
5575 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005576 } else {
5577 cpr.externals++;
5578 }
5579
5580 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005581 updateOomAdjLocked(cpr.app);
5582 }
5583
5584 Binder.restoreCallingIdentity(origId);
5585
5586 } else {
5587 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005588 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005589 resolveContentProvider(name,
5590 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005591 } catch (RemoteException ex) {
5592 }
5593 if (cpi == null) {
5594 return null;
5595 }
5596
Dianne Hackbornb424b632010-08-18 15:59:05 -07005597 String msg;
5598 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5599 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005600 }
5601
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005602 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005603 && !cpi.processName.equals("system")) {
5604 // If this content provider does not run in the system
5605 // process, and the system is not yet ready to run other
5606 // processes, then fail fast instead of hanging.
5607 throw new IllegalArgumentException(
5608 "Attempt to launch content provider before system ready");
5609 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005610
5611 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5612 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005613 final boolean firstClass = cpr == null;
5614 if (firstClass) {
5615 try {
5616 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005617 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005618 getApplicationInfo(
5619 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005620 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005621 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005622 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005623 + cpi.name);
5624 return null;
5625 }
5626 cpr = new ContentProviderRecord(cpi, ai);
5627 } catch (RemoteException ex) {
5628 // pm is in same process, this will never happen.
5629 }
5630 }
5631
5632 if (r != null && cpr.canRunHere(r)) {
5633 // If this is a multiprocess provider, then just return its
5634 // info and allow the caller to instantiate it. Only do
5635 // this if the provider is the same user as the caller's
5636 // process, or can run as root (so can be in any process).
5637 return cpr;
5638 }
5639
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005640 if (DEBUG_PROVIDER) {
5641 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005642 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005643 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005644 }
5645
5646 // This is single process, and our app is now connecting to it.
5647 // See if we are already in the process of launching this
5648 // provider.
5649 final int N = mLaunchingProviders.size();
5650 int i;
5651 for (i=0; i<N; i++) {
5652 if (mLaunchingProviders.get(i) == cpr) {
5653 break;
5654 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005655 }
5656
5657 // If the provider is not already being launched, then get it
5658 // started.
5659 if (i >= N) {
5660 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005661
5662 try {
5663 // Content provider is now in use, its package can't be stopped.
5664 try {
5665 AppGlobals.getPackageManager().setPackageStoppedState(
5666 cpr.appInfo.packageName, false);
5667 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005668 } catch (IllegalArgumentException e) {
5669 Slog.w(TAG, "Failed trying to unstop package "
5670 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005671 }
5672
5673 ProcessRecord proc = startProcessLocked(cpi.processName,
5674 cpr.appInfo, false, 0, "content provider",
5675 new ComponentName(cpi.applicationInfo.packageName,
5676 cpi.name), false);
5677 if (proc == null) {
5678 Slog.w(TAG, "Unable to launch app "
5679 + cpi.applicationInfo.packageName + "/"
5680 + cpi.applicationInfo.uid + " for provider "
5681 + name + ": process is bad");
5682 return null;
5683 }
5684 cpr.launchingApp = proc;
5685 mLaunchingProviders.add(cpr);
5686 } finally {
5687 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005689 }
5690
5691 // Make sure the provider is published (the same provider class
5692 // may be published under multiple names).
5693 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005694 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005695 }
5696 mProvidersByName.put(name, cpr);
5697
5698 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005699 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005700 "Adding provider requested by "
5701 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005702 + cpr.info.processName);
5703 Integer cnt = r.conProviders.get(cpr);
5704 if (cnt == null) {
5705 r.conProviders.put(cpr, new Integer(1));
5706 } else {
5707 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5708 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005709 cpr.clients.add(r);
5710 } else {
5711 cpr.externals++;
5712 }
5713 }
5714 }
5715
5716 // Wait for the provider to be published...
5717 synchronized (cpr) {
5718 while (cpr.provider == null) {
5719 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005720 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005721 + cpi.applicationInfo.packageName + "/"
5722 + cpi.applicationInfo.uid + " for provider "
5723 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005724 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005725 cpi.applicationInfo.packageName,
5726 cpi.applicationInfo.uid, name);
5727 return null;
5728 }
5729 try {
5730 cpr.wait();
5731 } catch (InterruptedException ex) {
5732 }
5733 }
5734 }
5735 return cpr;
5736 }
5737
5738 public final ContentProviderHolder getContentProvider(
5739 IApplicationThread caller, String name) {
5740 if (caller == null) {
5741 String msg = "null IApplicationThread when getting content provider "
5742 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005743 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005744 throw new SecurityException(msg);
5745 }
5746
5747 return getContentProviderImpl(caller, name);
5748 }
5749
5750 private ContentProviderHolder getContentProviderExternal(String name) {
5751 return getContentProviderImpl(null, name);
5752 }
5753
5754 /**
5755 * Drop a content provider from a ProcessRecord's bookkeeping
5756 * @param cpr
5757 */
5758 public void removeContentProvider(IApplicationThread caller, String name) {
5759 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005760 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005761 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005762 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005763 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005764 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005765 return;
5766 }
5767 final ProcessRecord r = getRecordForAppLocked(caller);
5768 if (r == null) {
5769 throw new SecurityException(
5770 "Unable to find app for caller " + caller +
5771 " when removing content provider " + name);
5772 }
5773 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005774 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5775 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005776 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005777 + r.info.processName + " from process "
5778 + localCpr.appInfo.processName);
5779 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005780 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005781 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005782 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005783 return;
5784 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005785 Integer cnt = r.conProviders.get(localCpr);
5786 if (cnt == null || cnt.intValue() <= 1) {
5787 localCpr.clients.remove(r);
5788 r.conProviders.remove(localCpr);
5789 } else {
5790 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5791 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005792 }
5793 updateOomAdjLocked();
5794 }
5795 }
5796
5797 private void removeContentProviderExternal(String name) {
5798 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005799 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005800 if(cpr == null) {
5801 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005802 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005803 return;
5804 }
5805
5806 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005807 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5808 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005809 localCpr.externals--;
5810 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005811 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005812 }
5813 updateOomAdjLocked();
5814 }
5815 }
5816
5817 public final void publishContentProviders(IApplicationThread caller,
5818 List<ContentProviderHolder> providers) {
5819 if (providers == null) {
5820 return;
5821 }
5822
5823 synchronized(this) {
5824 final ProcessRecord r = getRecordForAppLocked(caller);
5825 if (r == null) {
5826 throw new SecurityException(
5827 "Unable to find app for caller " + caller
5828 + " (pid=" + Binder.getCallingPid()
5829 + ") when publishing content providers");
5830 }
5831
5832 final long origId = Binder.clearCallingIdentity();
5833
5834 final int N = providers.size();
5835 for (int i=0; i<N; i++) {
5836 ContentProviderHolder src = providers.get(i);
5837 if (src == null || src.info == null || src.provider == null) {
5838 continue;
5839 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005840 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005841 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005842 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
5843 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005844 String names[] = dst.info.authority.split(";");
5845 for (int j = 0; j < names.length; j++) {
5846 mProvidersByName.put(names[j], dst);
5847 }
5848
5849 int NL = mLaunchingProviders.size();
5850 int j;
5851 for (j=0; j<NL; j++) {
5852 if (mLaunchingProviders.get(j) == dst) {
5853 mLaunchingProviders.remove(j);
5854 j--;
5855 NL--;
5856 }
5857 }
5858 synchronized (dst) {
5859 dst.provider = src.provider;
5860 dst.app = r;
5861 dst.notifyAll();
5862 }
5863 updateOomAdjLocked(r);
5864 }
5865 }
5866
5867 Binder.restoreCallingIdentity(origId);
5868 }
5869 }
5870
5871 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07005872 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005873 synchronized (mSelf) {
5874 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5875 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005876 if (providers != null) {
5877 for (int i=providers.size()-1; i>=0; i--) {
5878 ProviderInfo pi = (ProviderInfo)providers.get(i);
5879 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5880 Slog.w(TAG, "Not installing system proc provider " + pi.name
5881 + ": not system .apk");
5882 providers.remove(i);
5883 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005884 }
5885 }
5886 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005887 if (providers != null) {
5888 mSystemThread.installSystemProviders(providers);
5889 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005890
5891 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01005892
5893 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005894 }
5895
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005896 /**
5897 * Allows app to retrieve the MIME type of a URI without having permission
5898 * to access its content provider.
5899 *
5900 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5901 *
5902 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5903 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5904 */
5905 public String getProviderMimeType(Uri uri) {
5906 final String name = uri.getAuthority();
5907 final long ident = Binder.clearCallingIdentity();
5908 ContentProviderHolder holder = null;
5909
5910 try {
5911 holder = getContentProviderExternal(name);
5912 if (holder != null) {
5913 return holder.provider.getType(uri);
5914 }
5915 } catch (RemoteException e) {
5916 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5917 return null;
5918 } finally {
5919 if (holder != null) {
5920 removeContentProviderExternal(name);
5921 }
5922 Binder.restoreCallingIdentity(ident);
5923 }
5924
5925 return null;
5926 }
5927
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005928 // =========================================================
5929 // GLOBAL MANAGEMENT
5930 // =========================================================
5931
5932 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5933 ApplicationInfo info, String customProcess) {
5934 String proc = customProcess != null ? customProcess : info.processName;
5935 BatteryStatsImpl.Uid.Proc ps = null;
5936 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5937 synchronized (stats) {
5938 ps = stats.getProcessStatsLocked(info.uid, proc);
5939 }
5940 return new ProcessRecord(ps, thread, info, proc);
5941 }
5942
5943 final ProcessRecord addAppLocked(ApplicationInfo info) {
5944 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5945
5946 if (app == null) {
5947 app = newProcessRecordLocked(null, info, null);
5948 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005949 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005950 }
5951
Dianne Hackborne7f97212011-02-24 14:40:20 -08005952 // This package really, really can not be stopped.
5953 try {
5954 AppGlobals.getPackageManager().setPackageStoppedState(
5955 info.packageName, false);
5956 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005957 } catch (IllegalArgumentException e) {
5958 Slog.w(TAG, "Failed trying to unstop package "
5959 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005960 }
5961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005962 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5963 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5964 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07005965 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005966 }
5967 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5968 mPersistentStartingProcesses.add(app);
5969 startProcessLocked(app, "added application", app.processName);
5970 }
5971
5972 return app;
5973 }
5974
5975 public void unhandledBack() {
5976 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5977 "unhandledBack()");
5978
5979 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005980 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005981 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005982 TAG, "Performing unhandledBack(): stack size = " + count);
5983 if (count > 1) {
5984 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005985 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005986 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5987 Binder.restoreCallingIdentity(origId);
5988 }
5989 }
5990 }
5991
5992 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5993 String name = uri.getAuthority();
5994 ContentProviderHolder cph = getContentProviderExternal(name);
5995 ParcelFileDescriptor pfd = null;
5996 if (cph != null) {
5997 // We record the binder invoker's uid in thread-local storage before
5998 // going to the content provider to open the file. Later, in the code
5999 // that handles all permissions checks, we look for this uid and use
6000 // that rather than the Activity Manager's own uid. The effect is that
6001 // we do the check against the caller's permissions even though it looks
6002 // to the content provider like the Activity Manager itself is making
6003 // the request.
6004 sCallerIdentity.set(new Identity(
6005 Binder.getCallingPid(), Binder.getCallingUid()));
6006 try {
6007 pfd = cph.provider.openFile(uri, "r");
6008 } catch (FileNotFoundException e) {
6009 // do nothing; pfd will be returned null
6010 } finally {
6011 // Ensure that whatever happens, we clean up the identity state
6012 sCallerIdentity.remove();
6013 }
6014
6015 // We've got the fd now, so we're done with the provider.
6016 removeContentProviderExternal(name);
6017 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006018 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006019 }
6020 return pfd;
6021 }
6022
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006023 // Actually is sleeping or shutting down or whatever else in the future
6024 // is an inactive state.
6025 public boolean isSleeping() {
6026 return mSleeping || mShuttingDown;
6027 }
6028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006029 public void goingToSleep() {
6030 synchronized(this) {
6031 mSleeping = true;
6032 mWindowManager.setEventDispatching(false);
6033
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006034 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006035
6036 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006037 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006038 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6039 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006040 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006041 }
6042 }
6043
Dianne Hackborn55280a92009-05-07 15:53:46 -07006044 public boolean shutdown(int timeout) {
6045 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6046 != PackageManager.PERMISSION_GRANTED) {
6047 throw new SecurityException("Requires permission "
6048 + android.Manifest.permission.SHUTDOWN);
6049 }
6050
6051 boolean timedout = false;
6052
6053 synchronized(this) {
6054 mShuttingDown = true;
6055 mWindowManager.setEventDispatching(false);
6056
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006057 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006058 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006059 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006060 while (mMainStack.mResumedActivity != null
6061 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006062 long delay = endTime - System.currentTimeMillis();
6063 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006064 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006065 timedout = true;
6066 break;
6067 }
6068 try {
6069 this.wait();
6070 } catch (InterruptedException e) {
6071 }
6072 }
6073 }
6074 }
6075
6076 mUsageStatsService.shutdown();
6077 mBatteryStatsService.shutdown();
6078
6079 return timedout;
6080 }
6081
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006082 public final void activitySlept(IBinder token) {
6083 if (localLOGV) Slog.v(
6084 TAG, "Activity slept: token=" + token);
6085
6086 ActivityRecord r = null;
6087
6088 final long origId = Binder.clearCallingIdentity();
6089
6090 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006091 r = mMainStack.isInStackLocked(token);
6092 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006093 mMainStack.activitySleptLocked(r);
6094 }
6095 }
6096
6097 Binder.restoreCallingIdentity(origId);
6098 }
6099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006100 public void wakingUp() {
6101 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006102 mWindowManager.setEventDispatching(true);
6103 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006104 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006105 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006106 }
6107 }
6108
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006109 public void stopAppSwitches() {
6110 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6111 != PackageManager.PERMISSION_GRANTED) {
6112 throw new SecurityException("Requires permission "
6113 + android.Manifest.permission.STOP_APP_SWITCHES);
6114 }
6115
6116 synchronized(this) {
6117 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6118 + APP_SWITCH_DELAY_TIME;
6119 mDidAppSwitch = false;
6120 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6121 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6122 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6123 }
6124 }
6125
6126 public void resumeAppSwitches() {
6127 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6128 != PackageManager.PERMISSION_GRANTED) {
6129 throw new SecurityException("Requires permission "
6130 + android.Manifest.permission.STOP_APP_SWITCHES);
6131 }
6132
6133 synchronized(this) {
6134 // Note that we don't execute any pending app switches... we will
6135 // let those wait until either the timeout, or the next start
6136 // activity request.
6137 mAppSwitchesAllowedTime = 0;
6138 }
6139 }
6140
6141 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6142 String name) {
6143 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6144 return true;
6145 }
6146
6147 final int perm = checkComponentPermission(
6148 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006149 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006150 if (perm == PackageManager.PERMISSION_GRANTED) {
6151 return true;
6152 }
6153
Joe Onorato8a9b2202010-02-26 18:56:32 -08006154 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006155 return false;
6156 }
6157
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006158 public void setDebugApp(String packageName, boolean waitForDebugger,
6159 boolean persistent) {
6160 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6161 "setDebugApp()");
6162
6163 // Note that this is not really thread safe if there are multiple
6164 // callers into it at the same time, but that's not a situation we
6165 // care about.
6166 if (persistent) {
6167 final ContentResolver resolver = mContext.getContentResolver();
6168 Settings.System.putString(
6169 resolver, Settings.System.DEBUG_APP,
6170 packageName);
6171 Settings.System.putInt(
6172 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6173 waitForDebugger ? 1 : 0);
6174 }
6175
6176 synchronized (this) {
6177 if (!persistent) {
6178 mOrigDebugApp = mDebugApp;
6179 mOrigWaitForDebugger = mWaitForDebugger;
6180 }
6181 mDebugApp = packageName;
6182 mWaitForDebugger = waitForDebugger;
6183 mDebugTransient = !persistent;
6184 if (packageName != null) {
6185 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006186 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006187 Binder.restoreCallingIdentity(origId);
6188 }
6189 }
6190 }
6191
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006192 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6193 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6194 synchronized (this) {
6195 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6196 if (!isDebuggable) {
6197 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6198 throw new SecurityException("Process not debuggable: " + app.packageName);
6199 }
6200 }
6201 mProfileApp = processName;
6202 mProfileFile = profileFile;
6203 if (mProfileFd != null) {
6204 try {
6205 mProfileFd.close();
6206 } catch (IOException e) {
6207 }
6208 mProfileFd = null;
6209 }
6210 mProfileFd = profileFd;
6211 mProfileType = 0;
6212 mAutoStopProfiler = autoStopProfiler;
6213 }
6214 }
6215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006216 public void setAlwaysFinish(boolean enabled) {
6217 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6218 "setAlwaysFinish()");
6219
6220 Settings.System.putInt(
6221 mContext.getContentResolver(),
6222 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6223
6224 synchronized (this) {
6225 mAlwaysFinishActivities = enabled;
6226 }
6227 }
6228
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006229 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006230 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006231 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006232 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006233 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006234 }
6235 }
6236
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006237 public boolean isUserAMonkey() {
6238 // For now the fact that there is a controller implies
6239 // we have a monkey.
6240 synchronized (this) {
6241 return mController != null;
6242 }
6243 }
6244
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006245 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006246 synchronized (this) {
6247 mWatchers.register(watcher);
6248 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006249 }
6250
6251 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006252 synchronized (this) {
6253 mWatchers.unregister(watcher);
6254 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006255 }
6256
Jeff Sharkeya4620792011-05-20 15:29:23 -07006257 public void registerProcessObserver(IProcessObserver observer) {
6258 mProcessObservers.register(observer);
6259 }
6260
6261 public void unregisterProcessObserver(IProcessObserver observer) {
6262 mProcessObservers.unregister(observer);
6263 }
6264
Daniel Sandler69a48172010-06-23 16:29:36 -04006265 public void setImmersive(IBinder token, boolean immersive) {
6266 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006267 ActivityRecord r = mMainStack.isInStackLocked(token);
6268 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006269 throw new IllegalArgumentException();
6270 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006271 r.immersive = immersive;
6272 }
6273 }
6274
6275 public boolean isImmersive(IBinder token) {
6276 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006277 ActivityRecord r = mMainStack.isInStackLocked(token);
6278 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006279 throw new IllegalArgumentException();
6280 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006281 return r.immersive;
6282 }
6283 }
6284
6285 public boolean isTopActivityImmersive() {
6286 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006287 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006288 return (r != null) ? r.immersive : false;
6289 }
6290 }
6291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006292 public final void enterSafeMode() {
6293 synchronized(this) {
6294 // It only makes sense to do this before the system is ready
6295 // and started launching other packages.
6296 if (!mSystemReady) {
6297 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006298 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006299 } catch (RemoteException e) {
6300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006301 }
6302 }
6303 }
6304
Jeff Brownb09abc12011-01-13 21:08:27 -08006305 public final void showSafeModeOverlay() {
6306 View v = LayoutInflater.from(mContext).inflate(
6307 com.android.internal.R.layout.safe_mode, null);
6308 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6309 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6310 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6311 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6312 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6313 lp.format = v.getBackground().getOpacity();
6314 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6315 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6316 ((WindowManager)mContext.getSystemService(
6317 Context.WINDOW_SERVICE)).addView(v, lp);
6318 }
6319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006320 public void noteWakeupAlarm(IIntentSender sender) {
6321 if (!(sender instanceof PendingIntentRecord)) {
6322 return;
6323 }
6324 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6325 synchronized (stats) {
6326 if (mBatteryStatsService.isOnBattery()) {
6327 mBatteryStatsService.enforceCallingPermission();
6328 PendingIntentRecord rec = (PendingIntentRecord)sender;
6329 int MY_UID = Binder.getCallingUid();
6330 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6331 BatteryStatsImpl.Uid.Pkg pkg =
6332 stats.getPackageStatsLocked(uid, rec.key.packageName);
6333 pkg.incWakeupsLocked();
6334 }
6335 }
6336 }
6337
Dianne Hackborn64825172011-03-02 21:32:58 -08006338 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006339 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006340 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006341 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006342 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006343 // XXX Note: don't acquire main activity lock here, because the window
6344 // manager calls in with its locks held.
6345
6346 boolean killed = false;
6347 synchronized (mPidsSelfLocked) {
6348 int[] types = new int[pids.length];
6349 int worstType = 0;
6350 for (int i=0; i<pids.length; i++) {
6351 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6352 if (proc != null) {
6353 int type = proc.setAdj;
6354 types[i] = type;
6355 if (type > worstType) {
6356 worstType = type;
6357 }
6358 }
6359 }
6360
Dianne Hackborn64825172011-03-02 21:32:58 -08006361 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006362 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006363 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6364 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006365 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006366
6367 // If this is not a secure call, don't let it kill processes that
6368 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006369 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6370 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006371 }
6372
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006373 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006374 for (int i=0; i<pids.length; i++) {
6375 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6376 if (proc == null) {
6377 continue;
6378 }
6379 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006380 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006381 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006382 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6383 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006384 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006385 proc.killedBackground = true;
6386 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006387 }
6388 }
6389 }
6390 return killed;
6391 }
6392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006393 public final void startRunning(String pkg, String cls, String action,
6394 String data) {
6395 synchronized(this) {
6396 if (mStartRunning) {
6397 return;
6398 }
6399 mStartRunning = true;
6400 mTopComponent = pkg != null && cls != null
6401 ? new ComponentName(pkg, cls) : null;
6402 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6403 mTopData = data;
6404 if (!mSystemReady) {
6405 return;
6406 }
6407 }
6408
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006409 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006410 }
6411
6412 private void retrieveSettings() {
6413 final ContentResolver resolver = mContext.getContentResolver();
6414 String debugApp = Settings.System.getString(
6415 resolver, Settings.System.DEBUG_APP);
6416 boolean waitForDebugger = Settings.System.getInt(
6417 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6418 boolean alwaysFinishActivities = Settings.System.getInt(
6419 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6420
6421 Configuration configuration = new Configuration();
6422 Settings.System.getConfiguration(resolver, configuration);
6423
6424 synchronized (this) {
6425 mDebugApp = mOrigDebugApp = debugApp;
6426 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6427 mAlwaysFinishActivities = alwaysFinishActivities;
6428 // This happens before any activities are started, so we can
6429 // change mConfiguration in-place.
6430 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006431 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006432 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006433 }
6434 }
6435
6436 public boolean testIsSystemReady() {
6437 // no need to synchronize(this) just to read & return the value
6438 return mSystemReady;
6439 }
6440
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006441 private static File getCalledPreBootReceiversFile() {
6442 File dataDir = Environment.getDataDirectory();
6443 File systemDir = new File(dataDir, "system");
6444 File fname = new File(systemDir, "called_pre_boots.dat");
6445 return fname;
6446 }
6447
6448 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6449 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6450 File file = getCalledPreBootReceiversFile();
6451 FileInputStream fis = null;
6452 try {
6453 fis = new FileInputStream(file);
6454 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6455 int vers = dis.readInt();
6456 String codename = dis.readUTF();
6457 if (vers == android.os.Build.VERSION.SDK_INT
6458 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6459 int num = dis.readInt();
6460 while (num > 0) {
6461 num--;
6462 String pkg = dis.readUTF();
6463 String cls = dis.readUTF();
6464 lastDoneReceivers.add(new ComponentName(pkg, cls));
6465 }
6466 }
6467 } catch (FileNotFoundException e) {
6468 } catch (IOException e) {
6469 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6470 } finally {
6471 if (fis != null) {
6472 try {
6473 fis.close();
6474 } catch (IOException e) {
6475 }
6476 }
6477 }
6478 return lastDoneReceivers;
6479 }
6480
6481 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6482 File file = getCalledPreBootReceiversFile();
6483 FileOutputStream fos = null;
6484 DataOutputStream dos = null;
6485 try {
6486 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6487 fos = new FileOutputStream(file);
6488 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6489 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6490 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6491 dos.writeInt(list.size());
6492 for (int i=0; i<list.size(); i++) {
6493 dos.writeUTF(list.get(i).getPackageName());
6494 dos.writeUTF(list.get(i).getClassName());
6495 }
6496 } catch (IOException e) {
6497 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6498 file.delete();
6499 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006500 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006501 if (dos != null) {
6502 try {
6503 dos.close();
6504 } catch (IOException e) {
6505 // TODO Auto-generated catch block
6506 e.printStackTrace();
6507 }
6508 }
6509 }
6510 }
6511
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006512 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006513 synchronized(this) {
6514 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006515 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006516 return;
6517 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006518
6519 // Check to see if there are any update receivers to run.
6520 if (!mDidUpdate) {
6521 if (mWaitingUpdate) {
6522 return;
6523 }
6524 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6525 List<ResolveInfo> ris = null;
6526 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006527 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006528 intent, null, 0);
6529 } catch (RemoteException e) {
6530 }
6531 if (ris != null) {
6532 for (int i=ris.size()-1; i>=0; i--) {
6533 if ((ris.get(i).activityInfo.applicationInfo.flags
6534 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6535 ris.remove(i);
6536 }
6537 }
6538 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006539
6540 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6541
6542 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006543 for (int i=0; i<ris.size(); i++) {
6544 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006545 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6546 if (lastDoneReceivers.contains(comp)) {
6547 ris.remove(i);
6548 i--;
6549 }
6550 }
6551
6552 for (int i=0; i<ris.size(); i++) {
6553 ActivityInfo ai = ris.get(i).activityInfo;
6554 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6555 doneReceivers.add(comp);
6556 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006557 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006558 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006559 finisher = new IIntentReceiver.Stub() {
6560 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006561 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006562 boolean sticky) {
6563 // The raw IIntentReceiver interface is called
6564 // with the AM lock held, so redispatch to
6565 // execute our code without the lock.
6566 mHandler.post(new Runnable() {
6567 public void run() {
6568 synchronized (ActivityManagerService.this) {
6569 mDidUpdate = true;
6570 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006571 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006572 systemReady(goingCallback);
6573 }
6574 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006575 }
6576 };
6577 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006578 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006579 broadcastIntentLocked(null, null, intent, null, finisher,
6580 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006581 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006582 mWaitingUpdate = true;
6583 }
6584 }
6585 }
6586 if (mWaitingUpdate) {
6587 return;
6588 }
6589 mDidUpdate = true;
6590 }
6591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006592 mSystemReady = true;
6593 if (!mStartRunning) {
6594 return;
6595 }
6596 }
6597
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006598 ArrayList<ProcessRecord> procsToKill = null;
6599 synchronized(mPidsSelfLocked) {
6600 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6601 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6602 if (!isAllowedWhileBooting(proc.info)){
6603 if (procsToKill == null) {
6604 procsToKill = new ArrayList<ProcessRecord>();
6605 }
6606 procsToKill.add(proc);
6607 }
6608 }
6609 }
6610
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006611 synchronized(this) {
6612 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006613 for (int i=procsToKill.size()-1; i>=0; i--) {
6614 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006615 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006616 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006617 }
6618 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006619
6620 // Now that we have cleaned up any update processes, we
6621 // are ready to start launching real processes and know that
6622 // we won't trample on them any more.
6623 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006624 }
6625
Joe Onorato8a9b2202010-02-26 18:56:32 -08006626 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006627 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006628 SystemClock.uptimeMillis());
6629
6630 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006631 // Make sure we have no pre-ready processes sitting around.
6632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006633 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6634 ResolveInfo ri = mContext.getPackageManager()
6635 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006636 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006637 CharSequence errorMsg = null;
6638 if (ri != null) {
6639 ActivityInfo ai = ri.activityInfo;
6640 ApplicationInfo app = ai.applicationInfo;
6641 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6642 mTopAction = Intent.ACTION_FACTORY_TEST;
6643 mTopData = null;
6644 mTopComponent = new ComponentName(app.packageName,
6645 ai.name);
6646 } else {
6647 errorMsg = mContext.getResources().getText(
6648 com.android.internal.R.string.factorytest_not_system);
6649 }
6650 } else {
6651 errorMsg = mContext.getResources().getText(
6652 com.android.internal.R.string.factorytest_no_action);
6653 }
6654 if (errorMsg != null) {
6655 mTopAction = null;
6656 mTopData = null;
6657 mTopComponent = null;
6658 Message msg = Message.obtain();
6659 msg.what = SHOW_FACTORY_ERROR_MSG;
6660 msg.getData().putCharSequence("msg", errorMsg);
6661 mHandler.sendMessage(msg);
6662 }
6663 }
6664 }
6665
6666 retrieveSettings();
6667
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006668 if (goingCallback != null) goingCallback.run();
6669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006670 synchronized (this) {
6671 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6672 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006673 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006674 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006675 if (apps != null) {
6676 int N = apps.size();
6677 int i;
6678 for (i=0; i<N; i++) {
6679 ApplicationInfo info
6680 = (ApplicationInfo)apps.get(i);
6681 if (info != null &&
6682 !info.packageName.equals("android")) {
6683 addAppLocked(info);
6684 }
6685 }
6686 }
6687 } catch (RemoteException ex) {
6688 // pm is in same process, this will never happen.
6689 }
6690 }
6691
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006692 // Start up initial activity.
6693 mBooting = true;
6694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006695 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006696 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006697 Message msg = Message.obtain();
6698 msg.what = SHOW_UID_ERROR_MSG;
6699 mHandler.sendMessage(msg);
6700 }
6701 } catch (RemoteException e) {
6702 }
6703
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006704 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006705 }
6706 }
6707
Dan Egnorb7f03672009-12-09 16:22:32 -08006708 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006709 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006710 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006711 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006712 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006713 startAppProblemLocked(app);
6714 app.stopFreezingAllLocked();
6715 return handleAppCrashLocked(app);
6716 }
6717
Dan Egnorb7f03672009-12-09 16:22:32 -08006718 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006719 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006720 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006721 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006722 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6723 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006724 startAppProblemLocked(app);
6725 app.stopFreezingAllLocked();
6726 }
6727
6728 /**
6729 * Generate a process error record, suitable for attachment to a ProcessRecord.
6730 *
6731 * @param app The ProcessRecord in which the error occurred.
6732 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6733 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006734 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006735 * @param shortMsg Short message describing the crash.
6736 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006737 * @param stackTrace Full crash stack trace, may be null.
6738 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006739 * @return Returns a fully-formed AppErrorStateInfo record.
6740 */
6741 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006742 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006743 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006745 report.condition = condition;
6746 report.processName = app.processName;
6747 report.pid = app.pid;
6748 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006749 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006750 report.shortMsg = shortMsg;
6751 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006752 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006753
6754 return report;
6755 }
6756
Dan Egnor42471dd2010-01-07 17:25:22 -08006757 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006758 synchronized (this) {
6759 app.crashing = false;
6760 app.crashingReport = null;
6761 app.notResponding = false;
6762 app.notRespondingReport = null;
6763 if (app.anrDialog == fromDialog) {
6764 app.anrDialog = null;
6765 }
6766 if (app.waitDialog == fromDialog) {
6767 app.waitDialog = null;
6768 }
6769 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006770 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006771 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006772 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6773 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006774 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006775 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006776 }
6777 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006778
Dan Egnorb7f03672009-12-09 16:22:32 -08006779 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006780 long now = SystemClock.uptimeMillis();
6781
6782 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6783 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006784 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006785 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006786 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006787 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006788 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006789 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006790 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6791 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006792 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006793 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006794 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006795 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006796 }
6797 }
6798 if (!app.persistent) {
6799 // We don't want to start this process again until the user
6800 // explicitly does so... but for persistent process, we really
6801 // need to keep it running. If a persistent process is actually
6802 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006803 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006804 app.info.processName);
6805 mBadProcesses.put(app.info.processName, app.info.uid, now);
6806 app.bad = true;
6807 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6808 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006809 // Don't let services in this process be restarted and potentially
6810 // annoy the user repeatedly. Unless it is persistent, since those
6811 // processes run critical code.
6812 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006813 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006814 return false;
6815 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006816 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006817 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006818 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006819 if (r.app == app) {
6820 // If the top running activity is from this crashing
6821 // process, then terminate it to avoid getting in a loop.
6822 Slog.w(TAG, " Force finishing activity "
6823 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006824 int index = mMainStack.indexOfTokenLocked(r);
6825 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006826 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006827 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006828 // stopped, to avoid a situation where one will get
6829 // re-start our crashing activity once it gets resumed again.
6830 index--;
6831 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006832 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006833 if (r.state == ActivityState.RESUMED
6834 || r.state == ActivityState.PAUSING
6835 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006836 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006837 Slog.w(TAG, " Force finishing activity "
6838 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006839 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006840 Activity.RESULT_CANCELED, null, "crashed");
6841 }
6842 }
6843 }
6844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006845 }
6846
6847 // Bump up the crash count of any services currently running in the proc.
6848 if (app.services.size() != 0) {
6849 // Any services running in the application need to be placed
6850 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006851 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006852 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006853 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006854 sr.crashCount++;
6855 }
6856 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006857
6858 // If the crashing process is what we consider to be the "home process" and it has been
6859 // replaced by a third-party app, clear the package preferred activities from packages
6860 // with a home activity running in the process to prevent a repeatedly crashing app
6861 // from blocking the user to manually clear the list.
6862 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6863 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6864 Iterator it = mHomeProcess.activities.iterator();
6865 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006866 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006867 if (r.isHomeActivity) {
6868 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6869 try {
6870 ActivityThread.getPackageManager()
6871 .clearPackagePreferredActivities(r.packageName);
6872 } catch (RemoteException c) {
6873 // pm is in same process, this will never happen.
6874 }
6875 }
6876 }
6877 }
6878
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006879 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6880 return true;
6881 }
6882
6883 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006884 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6885 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006886 skipCurrentReceiverLocked(app);
6887 }
6888
6889 void skipCurrentReceiverLocked(ProcessRecord app) {
6890 boolean reschedule = false;
6891 BroadcastRecord r = app.curReceiver;
6892 if (r != null) {
6893 // The current broadcast is waiting for this app's receiver
6894 // to be finished. Looks like that's not going to happen, so
6895 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006896 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006897 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6898 r.resultExtras, r.resultAbort, true);
6899 reschedule = true;
6900 }
6901 r = mPendingBroadcast;
6902 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006903 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006904 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006905 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006906 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6907 r.resultExtras, r.resultAbort, true);
6908 reschedule = true;
6909 }
6910 if (reschedule) {
6911 scheduleBroadcastsLocked();
6912 }
6913 }
6914
Dan Egnor60d87622009-12-16 16:32:58 -08006915 /**
6916 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6917 * The application process will exit immediately after this call returns.
6918 * @param app object of the crashing app, null for the system server
6919 * @param crashInfo describing the exception
6920 */
6921 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006922 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006923
6924 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6925 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006926 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006927 crashInfo.exceptionClassName,
6928 crashInfo.exceptionMessage,
6929 crashInfo.throwFileName,
6930 crashInfo.throwLineNumber);
6931
Dan Egnor42471dd2010-01-07 17:25:22 -08006932 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006933
6934 crashApplication(r, crashInfo);
6935 }
6936
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006937 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006938 IBinder app,
6939 int violationMask,
6940 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006941 ProcessRecord r = findAppProcess(app, "StrictMode");
6942 if (r == null) {
6943 return;
6944 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006945
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006946 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006947 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006948 boolean logIt = true;
6949 synchronized (mAlreadyLoggedViolatedStacks) {
6950 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6951 logIt = false;
6952 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006953 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006954 // the relative pain numbers, without logging all
6955 // the stack traces repeatedly. We'd want to do
6956 // likewise in the client code, which also does
6957 // dup suppression, before the Binder call.
6958 } else {
6959 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6960 mAlreadyLoggedViolatedStacks.clear();
6961 }
6962 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6963 }
6964 }
6965 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006966 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006967 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006968 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006969
6970 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6971 AppErrorResult result = new AppErrorResult();
6972 synchronized (this) {
6973 final long origId = Binder.clearCallingIdentity();
6974
6975 Message msg = Message.obtain();
6976 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6977 HashMap<String, Object> data = new HashMap<String, Object>();
6978 data.put("result", result);
6979 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006980 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006981 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006982 msg.obj = data;
6983 mHandler.sendMessage(msg);
6984
6985 Binder.restoreCallingIdentity(origId);
6986 }
6987 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07006988 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006989 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006990 }
6991
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006992 // Depending on the policy in effect, there could be a bunch of
6993 // these in quick succession so we try to batch these together to
6994 // minimize disk writes, number of dropbox entries, and maximize
6995 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006996 private void logStrictModeViolationToDropBox(
6997 ProcessRecord process,
6998 StrictMode.ViolationInfo info) {
6999 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007000 return;
7001 }
7002 final boolean isSystemApp = process == null ||
7003 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7004 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7005 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7006 final DropBoxManager dbox = (DropBoxManager)
7007 mContext.getSystemService(Context.DROPBOX_SERVICE);
7008
7009 // Exit early if the dropbox isn't configured to accept this report type.
7010 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7011
7012 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007013 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007014 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7015 synchronized (sb) {
7016 bufferWasEmpty = sb.length() == 0;
7017 appendDropBoxProcessHeaders(process, sb);
7018 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7019 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007020 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7021 if (info.violationNumThisLoop != 0) {
7022 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7023 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007024 if (info.numAnimationsRunning != 0) {
7025 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7026 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007027 if (info.broadcastIntentAction != null) {
7028 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7029 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007030 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007031 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007032 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007033 if (info.numInstances != -1) {
7034 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7035 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007036 if (info.tags != null) {
7037 for (String tag : info.tags) {
7038 sb.append("Span-Tag: ").append(tag).append("\n");
7039 }
7040 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007041 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007042 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7043 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007044 }
7045 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007046
7047 // Only buffer up to ~64k. Various logging bits truncate
7048 // things at 128k.
7049 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007050 }
7051
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007052 // Flush immediately if the buffer's grown too large, or this
7053 // is a non-system app. Non-system apps are isolated with a
7054 // different tag & policy and not batched.
7055 //
7056 // Batching is useful during internal testing with
7057 // StrictMode settings turned up high. Without batching,
7058 // thousands of separate files could be created on boot.
7059 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007060 new Thread("Error dump: " + dropboxTag) {
7061 @Override
7062 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007063 String report;
7064 synchronized (sb) {
7065 report = sb.toString();
7066 sb.delete(0, sb.length());
7067 sb.trimToSize();
7068 }
7069 if (report.length() != 0) {
7070 dbox.addText(dropboxTag, report);
7071 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007072 }
7073 }.start();
7074 return;
7075 }
7076
7077 // System app batching:
7078 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007079 // An existing dropbox-writing thread is outstanding, so
7080 // we don't need to start it up. The existing thread will
7081 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007082 return;
7083 }
7084
7085 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7086 // (After this point, we shouldn't access AMS internal data structures.)
7087 new Thread("Error dump: " + dropboxTag) {
7088 @Override
7089 public void run() {
7090 // 5 second sleep to let stacks arrive and be batched together
7091 try {
7092 Thread.sleep(5000); // 5 seconds
7093 } catch (InterruptedException e) {}
7094
7095 String errorReport;
7096 synchronized (mStrictModeBuffer) {
7097 errorReport = mStrictModeBuffer.toString();
7098 if (errorReport.length() == 0) {
7099 return;
7100 }
7101 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7102 mStrictModeBuffer.trimToSize();
7103 }
7104 dbox.addText(dropboxTag, errorReport);
7105 }
7106 }.start();
7107 }
7108
Dan Egnor60d87622009-12-16 16:32:58 -08007109 /**
7110 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7111 * @param app object of the crashing app, null for the system server
7112 * @param tag reported by the caller
7113 * @param crashInfo describing the context of the error
7114 * @return true if the process should exit immediately (WTF is fatal)
7115 */
7116 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007117 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007118 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007119
7120 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7121 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007122 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007123 tag, crashInfo.exceptionMessage);
7124
Dan Egnor42471dd2010-01-07 17:25:22 -08007125 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007126
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007127 if (r != null && r.pid != Process.myPid() &&
7128 Settings.Secure.getInt(mContext.getContentResolver(),
7129 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007130 crashApplication(r, crashInfo);
7131 return true;
7132 } else {
7133 return false;
7134 }
7135 }
7136
7137 /**
7138 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7139 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7140 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007141 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007142 if (app == null) {
7143 return null;
7144 }
7145
7146 synchronized (this) {
7147 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7148 final int NA = apps.size();
7149 for (int ia=0; ia<NA; ia++) {
7150 ProcessRecord p = apps.valueAt(ia);
7151 if (p.thread != null && p.thread.asBinder() == app) {
7152 return p;
7153 }
7154 }
7155 }
7156
Dianne Hackborncb44d962011-03-10 17:02:27 -08007157 Slog.w(TAG, "Can't find mystery application for " + reason
7158 + " from pid=" + Binder.getCallingPid()
7159 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007160 return null;
7161 }
7162 }
7163
7164 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007165 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7166 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007167 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007168 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007169 // Watchdog thread ends up invoking this function (with
7170 // a null ProcessRecord) to add the stack file to dropbox.
7171 // Do not acquire a lock on this (am) in such cases, as it
7172 // could cause a potential deadlock, if and when watchdog
7173 // is invoked due to unavailability of lock on am and it
7174 // would prevent watchdog from killing system_server.
7175 if (process == null) {
7176 sb.append("Process: system_server\n");
7177 return;
7178 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007179 // Note: ProcessRecord 'process' is guarded by the service
7180 // instance. (notably process.pkgList, which could otherwise change
7181 // concurrently during execution of this method)
7182 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007183 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007184 sb.append("Process: system_server\n");
7185 } else {
7186 sb.append("Process: ").append(process.processName).append("\n");
7187 }
Dan Egnora455d192010-03-12 08:52:28 -08007188 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007189 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007190 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7191 for (String pkg : process.pkgList) {
7192 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007193 try {
Dan Egnora455d192010-03-12 08:52:28 -08007194 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7195 if (pi != null) {
7196 sb.append(" v").append(pi.versionCode);
7197 if (pi.versionName != null) {
7198 sb.append(" (").append(pi.versionName).append(")");
7199 }
7200 }
7201 } catch (RemoteException e) {
7202 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007203 }
Dan Egnora455d192010-03-12 08:52:28 -08007204 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007205 }
Dan Egnora455d192010-03-12 08:52:28 -08007206 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007207 }
7208
7209 private static String processClass(ProcessRecord process) {
7210 if (process == null || process.pid == MY_PID) {
7211 return "system_server";
7212 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7213 return "system_app";
7214 } else {
7215 return "data_app";
7216 }
7217 }
7218
7219 /**
7220 * Write a description of an error (crash, WTF, ANR) to the drop box.
7221 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7222 * @param process which caused the error, null means the system server
7223 * @param activity which triggered the error, null if unknown
7224 * @param parent activity related to the error, null if unknown
7225 * @param subject line related to the error, null if absent
7226 * @param report in long form describing the error, null if absent
7227 * @param logFile to include in the report, null if none
7228 * @param crashInfo giving an application stack trace, null if absent
7229 */
7230 public void addErrorToDropBox(String eventType,
7231 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7232 final String report, final File logFile,
7233 final ApplicationErrorReport.CrashInfo crashInfo) {
7234 // NOTE -- this must never acquire the ActivityManagerService lock,
7235 // otherwise the watchdog may be prevented from resetting the system.
7236
7237 final String dropboxTag = processClass(process) + "_" + eventType;
7238 final DropBoxManager dbox = (DropBoxManager)
7239 mContext.getSystemService(Context.DROPBOX_SERVICE);
7240
7241 // Exit early if the dropbox isn't configured to accept this report type.
7242 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7243
7244 final StringBuilder sb = new StringBuilder(1024);
7245 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007246 if (activity != null) {
7247 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7248 }
7249 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7250 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7251 }
7252 if (parent != null && parent != activity) {
7253 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7254 }
7255 if (subject != null) {
7256 sb.append("Subject: ").append(subject).append("\n");
7257 }
7258 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007259 if (Debug.isDebuggerConnected()) {
7260 sb.append("Debugger: Connected\n");
7261 }
Dan Egnora455d192010-03-12 08:52:28 -08007262 sb.append("\n");
7263
7264 // Do the rest in a worker thread to avoid blocking the caller on I/O
7265 // (After this point, we shouldn't access AMS internal data structures.)
7266 Thread worker = new Thread("Error dump: " + dropboxTag) {
7267 @Override
7268 public void run() {
7269 if (report != null) {
7270 sb.append(report);
7271 }
7272 if (logFile != null) {
7273 try {
7274 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7275 } catch (IOException e) {
7276 Slog.e(TAG, "Error reading " + logFile, e);
7277 }
7278 }
7279 if (crashInfo != null && crashInfo.stackTrace != null) {
7280 sb.append(crashInfo.stackTrace);
7281 }
7282
7283 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7284 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7285 if (lines > 0) {
7286 sb.append("\n");
7287
7288 // Merge several logcat streams, and take the last N lines
7289 InputStreamReader input = null;
7290 try {
7291 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7292 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7293 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7294
7295 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7296 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7297 input = new InputStreamReader(logcat.getInputStream());
7298
7299 int num;
7300 char[] buf = new char[8192];
7301 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7302 } catch (IOException e) {
7303 Slog.e(TAG, "Error running logcat", e);
7304 } finally {
7305 if (input != null) try { input.close(); } catch (IOException e) {}
7306 }
7307 }
7308
7309 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007310 }
Dan Egnora455d192010-03-12 08:52:28 -08007311 };
7312
7313 if (process == null || process.pid == MY_PID) {
7314 worker.run(); // We may be about to die -- need to run this synchronously
7315 } else {
7316 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007317 }
7318 }
7319
7320 /**
7321 * Bring up the "unexpected error" dialog box for a crashing app.
7322 * Deal with edge cases (intercepts from instrumented applications,
7323 * ActivityController, error intent receivers, that sort of thing).
7324 * @param r the application crashing
7325 * @param crashInfo describing the failure
7326 */
7327 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007328 long timeMillis = System.currentTimeMillis();
7329 String shortMsg = crashInfo.exceptionClassName;
7330 String longMsg = crashInfo.exceptionMessage;
7331 String stackTrace = crashInfo.stackTrace;
7332 if (shortMsg != null && longMsg != null) {
7333 longMsg = shortMsg + ": " + longMsg;
7334 } else if (shortMsg != null) {
7335 longMsg = shortMsg;
7336 }
7337
Dan Egnor60d87622009-12-16 16:32:58 -08007338 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007339 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007340 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007341 try {
7342 String name = r != null ? r.processName : null;
7343 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007344 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007345 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007346 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007347 + " at watcher's request");
7348 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007349 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007350 }
7351 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007352 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007353 }
7354 }
7355
7356 final long origId = Binder.clearCallingIdentity();
7357
7358 // If this process is running instrumentation, finish it.
7359 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007360 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007361 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007362 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7363 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007364 Bundle info = new Bundle();
7365 info.putString("shortMsg", shortMsg);
7366 info.putString("longMsg", longMsg);
7367 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7368 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007369 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007370 }
7371
Dan Egnor60d87622009-12-16 16:32:58 -08007372 // If we can't identify the process or it's already exceeded its crash quota,
7373 // quit right away without showing a crash dialog.
7374 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007375 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007376 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007377 }
7378
7379 Message msg = Message.obtain();
7380 msg.what = SHOW_ERROR_MSG;
7381 HashMap data = new HashMap();
7382 data.put("result", result);
7383 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007384 msg.obj = data;
7385 mHandler.sendMessage(msg);
7386
7387 Binder.restoreCallingIdentity(origId);
7388 }
7389
7390 int res = result.get();
7391
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007392 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007393 synchronized (this) {
7394 if (r != null) {
7395 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7396 SystemClock.uptimeMillis());
7397 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007398 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007399 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007400 }
7401 }
7402
7403 if (appErrorIntent != null) {
7404 try {
7405 mContext.startActivity(appErrorIntent);
7406 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007407 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007409 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007410 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007411
7412 Intent createAppErrorIntentLocked(ProcessRecord r,
7413 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7414 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007415 if (report == null) {
7416 return null;
7417 }
7418 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7419 result.setComponent(r.errorReportReceiver);
7420 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7421 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7422 return result;
7423 }
7424
Dan Egnorb7f03672009-12-09 16:22:32 -08007425 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7426 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007427 if (r.errorReportReceiver == null) {
7428 return null;
7429 }
7430
7431 if (!r.crashing && !r.notResponding) {
7432 return null;
7433 }
7434
Dan Egnorb7f03672009-12-09 16:22:32 -08007435 ApplicationErrorReport report = new ApplicationErrorReport();
7436 report.packageName = r.info.packageName;
7437 report.installerPackageName = r.errorReportReceiver.getPackageName();
7438 report.processName = r.processName;
7439 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007440 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007441
Dan Egnorb7f03672009-12-09 16:22:32 -08007442 if (r.crashing) {
7443 report.type = ApplicationErrorReport.TYPE_CRASH;
7444 report.crashInfo = crashInfo;
7445 } else if (r.notResponding) {
7446 report.type = ApplicationErrorReport.TYPE_ANR;
7447 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007448
Dan Egnorb7f03672009-12-09 16:22:32 -08007449 report.anrInfo.activity = r.notRespondingReport.tag;
7450 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7451 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007452 }
7453
Dan Egnorb7f03672009-12-09 16:22:32 -08007454 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007455 }
7456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007457 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7458 // assume our apps are happy - lazy create the list
7459 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7460
7461 synchronized (this) {
7462
7463 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007464 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7465 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007466 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7467 // This one's in trouble, so we'll generate a report for it
7468 // crashes are higher priority (in case there's a crash *and* an anr)
7469 ActivityManager.ProcessErrorStateInfo report = null;
7470 if (app.crashing) {
7471 report = app.crashingReport;
7472 } else if (app.notResponding) {
7473 report = app.notRespondingReport;
7474 }
7475
7476 if (report != null) {
7477 if (errList == null) {
7478 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7479 }
7480 errList.add(report);
7481 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007482 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007483 " crashing = " + app.crashing +
7484 " notResponding = " + app.notResponding);
7485 }
7486 }
7487 }
7488 }
7489
7490 return errList;
7491 }
7492
7493 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7494 // Lazy instantiation of list
7495 List<ActivityManager.RunningAppProcessInfo> runList = null;
7496 synchronized (this) {
7497 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007498 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7499 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007500 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7501 // Generate process state info for running application
7502 ActivityManager.RunningAppProcessInfo currApp =
7503 new ActivityManager.RunningAppProcessInfo(app.processName,
7504 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007505 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007506 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007507 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007508 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007509 if (app.persistent) {
7510 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007512 int adj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007513 if (adj >= ProcessList.EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007514 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007515 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007516 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007517 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7518 } else if (adj >= ProcessList.HOME_APP_ADJ) {
The Android Open Source Project4df24232009-03-05 14:34:35 -08007519 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7520 currApp.lru = 0;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007521 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007522 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007523 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007524 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007525 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007526 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007527 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007528 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7529 } else {
7530 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7531 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007532 currApp.importanceReasonCode = app.adjTypeCode;
7533 if (app.adjSource instanceof ProcessRecord) {
7534 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007535 } else if (app.adjSource instanceof ActivityRecord) {
7536 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007537 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7538 }
7539 if (app.adjTarget instanceof ComponentName) {
7540 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7541 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007542 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007543 // + " lru=" + currApp.lru);
7544 if (runList == null) {
7545 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7546 }
7547 runList.add(currApp);
7548 }
7549 }
7550 }
7551 return runList;
7552 }
7553
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007554 public List<ApplicationInfo> getRunningExternalApplications() {
7555 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7556 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7557 if (runningApps != null && runningApps.size() > 0) {
7558 Set<String> extList = new HashSet<String>();
7559 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7560 if (app.pkgList != null) {
7561 for (String pkg : app.pkgList) {
7562 extList.add(pkg);
7563 }
7564 }
7565 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007566 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007567 for (String pkg : extList) {
7568 try {
7569 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7570 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7571 retList.add(info);
7572 }
7573 } catch (RemoteException e) {
7574 }
7575 }
7576 }
7577 return retList;
7578 }
7579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007580 @Override
7581 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007582 if (checkCallingPermission(android.Manifest.permission.DUMP)
7583 != PackageManager.PERMISSION_GRANTED) {
7584 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7585 + Binder.getCallingPid()
7586 + ", uid=" + Binder.getCallingUid()
7587 + " without permission "
7588 + android.Manifest.permission.DUMP);
7589 return;
7590 }
7591
7592 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007593 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007594
7595 int opti = 0;
7596 while (opti < args.length) {
7597 String opt = args[opti];
7598 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7599 break;
7600 }
7601 opti++;
7602 if ("-a".equals(opt)) {
7603 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007604 } else if ("-c".equals(opt)) {
7605 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007606 } else if ("-h".equals(opt)) {
7607 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007608 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007609 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007610 pw.println(" a[ctivities]: activity stack state");
7611 pw.println(" b[roadcasts]: broadcast state");
7612 pw.println(" i[ntents]: pending intent state");
7613 pw.println(" p[rocesses]: process state");
7614 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007615 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7616 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007617 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007618 pw.println(" all: dump all activities");
7619 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007620 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007621 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7622 pw.println(" a partial substring in a component name, a");
7623 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007624 pw.println(" -a: include all available server state.");
7625 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007626 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007627 } else {
7628 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007629 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007630 }
7631
7632 // Is the caller requesting to dump a particular piece of data?
7633 if (opti < args.length) {
7634 String cmd = args[opti];
7635 opti++;
7636 if ("activities".equals(cmd) || "a".equals(cmd)) {
7637 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007638 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007639 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007640 return;
7641 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7642 synchronized (this) {
7643 dumpBroadcastsLocked(fd, pw, args, opti, true);
7644 }
7645 return;
7646 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7647 synchronized (this) {
7648 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7649 }
7650 return;
7651 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7652 synchronized (this) {
7653 dumpProcessesLocked(fd, pw, args, opti, true);
7654 }
7655 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007656 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7657 synchronized (this) {
7658 dumpOomLocked(fd, pw, args, opti, true);
7659 }
7660 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007661 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7662 synchronized (this) {
7663 dumpProvidersLocked(fd, pw, args, opti, true);
7664 }
7665 return;
7666 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007667 String[] newArgs;
7668 String name;
7669 if (opti >= args.length) {
7670 name = null;
7671 newArgs = EMPTY_STRING_ARRAY;
7672 } else {
7673 name = args[opti];
7674 opti++;
7675 newArgs = new String[args.length - opti];
7676 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7677 }
7678 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7679 pw.println("No services match: " + name);
7680 pw.println("Use -h for help.");
7681 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007682 return;
7683 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7684 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007685 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007686 }
7687 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007688 } else {
7689 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007690 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7691 pw.println("Bad activity command, or no activities match: " + cmd);
7692 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007693 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007694 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007695 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007696 }
7697
7698 // No piece of data specified, dump everything.
7699 synchronized (this) {
7700 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007701 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007702 if (needSep) {
7703 pw.println(" ");
7704 }
7705 if (dumpAll) {
7706 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007707 }
7708 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7709 if (needSep) {
7710 pw.println(" ");
7711 }
7712 if (dumpAll) {
7713 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007714 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007715 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007716 if (needSep) {
7717 pw.println(" ");
7718 }
7719 if (dumpAll) {
7720 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007721 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007722 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007723 if (needSep) {
7724 pw.println(" ");
7725 }
7726 if (dumpAll) {
7727 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007728 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007729 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007730 if (needSep) {
7731 pw.println(" ");
7732 }
7733 if (dumpAll) {
7734 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007735 }
7736 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7737 }
7738 }
7739
7740 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007741 int opti, boolean dumpAll, boolean dumpClient) {
7742 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7743 pw.println(" Main stack:");
7744 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007745 pw.println(" ");
7746 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007747 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007748 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007749 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007750 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007751 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7752 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007753 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007754 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007755 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007756 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007757 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7758 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007759 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007760 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7761 pw.println(" ");
7762 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007763 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7764 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007765 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007766 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007767 pw.println(" ");
7768 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007769 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7770 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007772
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007773 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007774 if (mMainStack.mPausingActivity != null) {
7775 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7776 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007777 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007778 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007779 if (dumpAll) {
7780 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7781 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7782 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007783
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007784 if (mRecentTasks.size() > 0) {
7785 pw.println();
7786 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007787
7788 final int N = mRecentTasks.size();
7789 for (int i=0; i<N; i++) {
7790 TaskRecord tr = mRecentTasks.get(i);
7791 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7792 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007793 if (dumpAll) {
7794 mRecentTasks.get(i).dump(pw, " ");
7795 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007796 }
7797 }
7798
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007799 if (dumpAll) {
7800 pw.println(" ");
7801 pw.println(" mCurTask: " + mCurTask);
7802 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007803
7804 return true;
7805 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007806
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007807 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7808 int opti, boolean dumpAll) {
7809 boolean needSep = false;
7810 int numPers = 0;
7811
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007812 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7813
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007814 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007815 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7816 final int NA = procs.size();
7817 for (int ia=0; ia<NA; ia++) {
7818 if (!needSep) {
7819 pw.println(" All known processes:");
7820 needSep = true;
7821 }
7822 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007823 pw.print(r.persistent ? " *PERS*" : " *APP*");
7824 pw.print(" UID "); pw.print(procs.keyAt(ia));
7825 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007826 r.dump(pw, " ");
7827 if (r.persistent) {
7828 numPers++;
7829 }
7830 }
7831 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007832 }
7833
7834 if (mLruProcesses.size() > 0) {
7835 if (needSep) pw.println(" ");
7836 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007837 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007838 dumpProcessOomList(pw, this, mLruProcesses, " ",
7839 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007840 needSep = true;
7841 }
7842
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007843 if (dumpAll) {
7844 synchronized (mPidsSelfLocked) {
7845 if (mPidsSelfLocked.size() > 0) {
7846 if (needSep) pw.println(" ");
7847 needSep = true;
7848 pw.println(" PID mappings:");
7849 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7850 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7851 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007853 }
7854 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007855 }
7856
7857 if (mForegroundProcesses.size() > 0) {
7858 if (needSep) pw.println(" ");
7859 needSep = true;
7860 pw.println(" Foreground Processes:");
7861 for (int i=0; i<mForegroundProcesses.size(); i++) {
7862 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7863 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007864 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007865 }
7866
7867 if (mPersistentStartingProcesses.size() > 0) {
7868 if (needSep) pw.println(" ");
7869 needSep = true;
7870 pw.println(" Persisent processes that are starting:");
7871 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007872 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007873 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007874
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007875 if (mRemovedProcesses.size() > 0) {
7876 if (needSep) pw.println(" ");
7877 needSep = true;
7878 pw.println(" Processes that are being removed:");
7879 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007880 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007881 }
7882
7883 if (mProcessesOnHold.size() > 0) {
7884 if (needSep) pw.println(" ");
7885 needSep = true;
7886 pw.println(" Processes that are on old until the system is ready:");
7887 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007888 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007889 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007890
Dianne Hackborn287952c2010-09-22 22:34:31 -07007891 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007892
7893 if (mProcessCrashTimes.getMap().size() > 0) {
7894 if (needSep) pw.println(" ");
7895 needSep = true;
7896 pw.println(" Time since processes crashed:");
7897 long now = SystemClock.uptimeMillis();
7898 for (Map.Entry<String, SparseArray<Long>> procs
7899 : mProcessCrashTimes.getMap().entrySet()) {
7900 SparseArray<Long> uids = procs.getValue();
7901 final int N = uids.size();
7902 for (int i=0; i<N; i++) {
7903 pw.print(" Process "); pw.print(procs.getKey());
7904 pw.print(" uid "); pw.print(uids.keyAt(i));
7905 pw.print(": last crashed ");
7906 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007907 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007908 }
7909 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007910 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007911
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007912 if (mBadProcesses.getMap().size() > 0) {
7913 if (needSep) pw.println(" ");
7914 needSep = true;
7915 pw.println(" Bad processes:");
7916 for (Map.Entry<String, SparseArray<Long>> procs
7917 : mBadProcesses.getMap().entrySet()) {
7918 SparseArray<Long> uids = procs.getValue();
7919 final int N = uids.size();
7920 for (int i=0; i<N; i++) {
7921 pw.print(" Bad process "); pw.print(procs.getKey());
7922 pw.print(" uid "); pw.print(uids.keyAt(i));
7923 pw.print(": crashed at time ");
7924 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007925 }
7926 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007927 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007928
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007929 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007930 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007931 if (mHeavyWeightProcess != null) {
7932 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7933 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007934 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007935 if (dumpAll) {
7936 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07007937 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07007938 pw.println(" mScreenCompatPackages:");
7939 for (Map.Entry<String, Integer> entry
7940 : mCompatModePackages.getPackages().entrySet()) {
7941 String pkg = entry.getKey();
7942 int mode = entry.getValue();
7943 pw.print(" "); pw.print(pkg); pw.print(": ");
7944 pw.print(mode); pw.println();
7945 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07007946 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007947 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007948 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7949 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7950 || mOrigWaitForDebugger) {
7951 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7952 + " mDebugTransient=" + mDebugTransient
7953 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7954 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07007955 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
7956 || mProfileFd != null) {
7957 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
7958 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
7959 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
7960 + mAutoStopProfiler);
7961 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007962 if (mAlwaysFinishActivities || mController != null) {
7963 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7964 + " mController=" + mController);
7965 }
7966 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007967 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007968 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007969 + " mProcessesReady=" + mProcessesReady
7970 + " mSystemReady=" + mSystemReady);
7971 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007972 + " mBooted=" + mBooted
7973 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007974 pw.print(" mLastPowerCheckRealtime=");
7975 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7976 pw.println("");
7977 pw.print(" mLastPowerCheckUptime=");
7978 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7979 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007980 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7981 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007982 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007983 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007984
7985 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986 }
7987
Dianne Hackborn287952c2010-09-22 22:34:31 -07007988 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7989 int opti, boolean needSep, boolean dumpAll) {
7990 if (mProcessesToGc.size() > 0) {
7991 if (needSep) pw.println(" ");
7992 needSep = true;
7993 pw.println(" Processes that are waiting to GC:");
7994 long now = SystemClock.uptimeMillis();
7995 for (int i=0; i<mProcessesToGc.size(); i++) {
7996 ProcessRecord proc = mProcessesToGc.get(i);
7997 pw.print(" Process "); pw.println(proc);
7998 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7999 pw.print(", last gced=");
8000 pw.print(now-proc.lastRequestedGc);
8001 pw.print(" ms ago, last lowMem=");
8002 pw.print(now-proc.lastLowMemory);
8003 pw.println(" ms ago");
8004
8005 }
8006 }
8007 return needSep;
8008 }
8009
8010 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8011 int opti, boolean dumpAll) {
8012 boolean needSep = false;
8013
8014 if (mLruProcesses.size() > 0) {
8015 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8016
8017 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8018 @Override
8019 public int compare(ProcessRecord object1, ProcessRecord object2) {
8020 if (object1.setAdj != object2.setAdj) {
8021 return object1.setAdj > object2.setAdj ? -1 : 1;
8022 }
8023 if (object1.setSchedGroup != object2.setSchedGroup) {
8024 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8025 }
8026 if (object1.keeping != object2.keeping) {
8027 return object1.keeping ? -1 : 1;
8028 }
8029 if (object1.pid != object2.pid) {
8030 return object1.pid > object2.pid ? -1 : 1;
8031 }
8032 return 0;
8033 }
8034 };
8035
8036 Collections.sort(procs, comparator);
8037
8038 if (needSep) pw.println(" ");
8039 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008040 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008041 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8042 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
8043 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8044 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8045 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8046 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8047 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8048 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
8049 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8050 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8051 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008052
8053 if (needSep) pw.println(" ");
8054 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008055 pw.println(" Process OOM control:");
8056 dumpProcessOomList(pw, this, procs, " ",
8057 "Proc", "PERS", true);
8058 needSep = true;
8059 }
8060
8061 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8062
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008063 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008064 pw.println(" mHomeProcess: " + mHomeProcess);
8065 if (mHeavyWeightProcess != null) {
8066 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8067 }
8068
8069 return true;
8070 }
8071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008072 /**
8073 * There are three ways to call this:
8074 * - no service specified: dump all the services
8075 * - a flattened component name that matched an existing service was specified as the
8076 * first arg: dump that one service
8077 * - the first arg isn't the flattened component name of an existing service:
8078 * dump all services whose component contains the first arg as a substring
8079 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008080 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8081 int opti, boolean dumpAll) {
8082 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008083
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008084 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008085 synchronized (this) {
8086 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008087 services.add(r1);
8088 }
8089 }
8090 } else {
8091 ComponentName componentName = name != null
8092 ? ComponentName.unflattenFromString(name) : null;
8093 int objectId = 0;
8094 if (componentName == null) {
8095 // Not a '/' separated full component name; maybe an object ID?
8096 try {
8097 objectId = Integer.parseInt(name, 16);
8098 name = null;
8099 componentName = null;
8100 } catch (RuntimeException e) {
8101 }
8102 }
8103
8104 synchronized (this) {
8105 for (ServiceRecord r1 : mServices.values()) {
8106 if (componentName != null) {
8107 if (r1.name.equals(componentName)) {
8108 services.add(r1);
8109 }
8110 } else if (name != null) {
8111 if (r1.name.flattenToString().contains(name)) {
8112 services.add(r1);
8113 }
8114 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008115 services.add(r1);
8116 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008117 }
8118 }
8119 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008120
8121 if (services.size() <= 0) {
8122 return false;
8123 }
8124
8125 boolean needSep = false;
8126 for (int i=0; i<services.size(); i++) {
8127 if (needSep) {
8128 pw.println();
8129 }
8130 needSep = true;
8131 dumpService("", fd, pw, services.get(i), args, dumpAll);
8132 }
8133 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008134 }
8135
8136 /**
8137 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8138 * there is a thread associated with the service.
8139 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008140 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8141 final ServiceRecord r, String[] args, boolean dumpAll) {
8142 String innerPrefix = prefix + " ";
8143 synchronized (this) {
8144 pw.print(prefix); pw.print("SERVICE ");
8145 pw.print(r.shortName); pw.print(" ");
8146 pw.print(Integer.toHexString(System.identityHashCode(r)));
8147 pw.print(" pid=");
8148 if (r.app != null) pw.println(r.app.pid);
8149 else pw.println("(not running)");
8150 if (dumpAll) {
8151 r.dump(pw, innerPrefix);
8152 }
8153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008154 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008155 pw.print(prefix); pw.println(" Client:");
8156 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008157 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008158 TransferPipe tp = new TransferPipe();
8159 try {
8160 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8161 tp.setBufferPrefix(prefix + " ");
8162 tp.go(fd);
8163 } finally {
8164 tp.kill();
8165 }
8166 } catch (IOException e) {
8167 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008168 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008169 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008170 }
8171 }
8172 }
8173
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008174 static class ItemMatcher {
8175 ArrayList<ComponentName> components;
8176 ArrayList<String> strings;
8177 ArrayList<Integer> objects;
8178 boolean all;
8179
8180 ItemMatcher() {
8181 all = true;
8182 }
8183
8184 void build(String name) {
8185 ComponentName componentName = ComponentName.unflattenFromString(name);
8186 if (componentName != null) {
8187 if (components == null) {
8188 components = new ArrayList<ComponentName>();
8189 }
8190 components.add(componentName);
8191 all = false;
8192 } else {
8193 int objectId = 0;
8194 // Not a '/' separated full component name; maybe an object ID?
8195 try {
8196 objectId = Integer.parseInt(name, 16);
8197 if (objects == null) {
8198 objects = new ArrayList<Integer>();
8199 }
8200 objects.add(objectId);
8201 all = false;
8202 } catch (RuntimeException e) {
8203 // Not an integer; just do string match.
8204 if (strings == null) {
8205 strings = new ArrayList<String>();
8206 }
8207 strings.add(name);
8208 all = false;
8209 }
8210 }
8211 }
8212
8213 int build(String[] args, int opti) {
8214 for (; opti<args.length; opti++) {
8215 String name = args[opti];
8216 if ("--".equals(name)) {
8217 return opti+1;
8218 }
8219 build(name);
8220 }
8221 return opti;
8222 }
8223
8224 boolean match(Object object, ComponentName comp) {
8225 if (all) {
8226 return true;
8227 }
8228 if (components != null) {
8229 for (int i=0; i<components.size(); i++) {
8230 if (components.get(i).equals(comp)) {
8231 return true;
8232 }
8233 }
8234 }
8235 if (objects != null) {
8236 for (int i=0; i<objects.size(); i++) {
8237 if (System.identityHashCode(object) == objects.get(i)) {
8238 return true;
8239 }
8240 }
8241 }
8242 if (strings != null) {
8243 String flat = comp.flattenToString();
8244 for (int i=0; i<strings.size(); i++) {
8245 if (flat.contains(strings.get(i))) {
8246 return true;
8247 }
8248 }
8249 }
8250 return false;
8251 }
8252 }
8253
Dianne Hackborn625ac272010-09-17 18:29:22 -07008254 /**
8255 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008256 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008257 * - the cmd arg isn't the flattened component name of an existing activity:
8258 * dump all activity whose component contains the cmd as a substring
8259 * - A hex number of the ActivityRecord object instance.
8260 */
8261 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8262 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008263 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008264
8265 if ("all".equals(name)) {
8266 synchronized (this) {
8267 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008268 activities.add(r1);
8269 }
8270 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008271 } else if ("top".equals(name)) {
8272 synchronized (this) {
8273 final int N = mMainStack.mHistory.size();
8274 if (N > 0) {
8275 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8276 }
8277 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008278 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008279 ItemMatcher matcher = new ItemMatcher();
8280 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008281
8282 synchronized (this) {
8283 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008284 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008285 activities.add(r1);
8286 }
8287 }
8288 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008289 }
8290
8291 if (activities.size() <= 0) {
8292 return false;
8293 }
8294
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008295 String[] newArgs = new String[args.length - opti];
8296 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8297
Dianne Hackborn30d71892010-12-11 10:37:55 -08008298 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008299 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008300 for (int i=activities.size()-1; i>=0; i--) {
8301 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008302 if (needSep) {
8303 pw.println();
8304 }
8305 needSep = true;
8306 synchronized (this) {
8307 if (lastTask != r.task) {
8308 lastTask = r.task;
8309 pw.print("TASK "); pw.print(lastTask.affinity);
8310 pw.print(" id="); pw.println(lastTask.taskId);
8311 if (dumpAll) {
8312 lastTask.dump(pw, " ");
8313 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008314 }
8315 }
8316 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008317 }
8318 return true;
8319 }
8320
8321 /**
8322 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8323 * there is a thread associated with the activity.
8324 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008325 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008326 final ActivityRecord r, String[] args, boolean dumpAll) {
8327 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008328 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008329 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8330 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8331 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008332 if (r.app != null) pw.println(r.app.pid);
8333 else pw.println("(not running)");
8334 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008335 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008336 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008337 }
8338 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008339 // flush anything that is already in the PrintWriter since the thread is going
8340 // to write to the file descriptor directly
8341 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008342 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008343 TransferPipe tp = new TransferPipe();
8344 try {
8345 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8346 innerPrefix, args);
8347 tp.go(fd);
8348 } finally {
8349 tp.kill();
8350 }
8351 } catch (IOException e) {
8352 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008353 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008354 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008355 }
8356 }
8357 }
8358
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008359 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8360 int opti, boolean dumpAll) {
8361 boolean needSep = false;
8362
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008363 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008364 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008365 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008366 pw.println(" Registered Receivers:");
8367 Iterator it = mRegisteredReceivers.values().iterator();
8368 while (it.hasNext()) {
8369 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008370 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008371 r.dump(pw, " ");
8372 }
8373 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008374
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008375 pw.println();
8376 pw.println(" Receiver Resolver Table:");
8377 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008378 needSep = true;
8379 }
8380
8381 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8382 || mPendingBroadcast != null) {
8383 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008384 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008385 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008386 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008387 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8388 pw.println(" Broadcast #" + i + ":");
8389 mParallelBroadcasts.get(i).dump(pw, " ");
8390 }
8391 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008392 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008393 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008394 }
8395 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8396 pw.println(" Serialized Broadcast #" + i + ":");
8397 mOrderedBroadcasts.get(i).dump(pw, " ");
8398 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008399 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008400 pw.println(" Pending broadcast:");
8401 if (mPendingBroadcast != null) {
8402 mPendingBroadcast.dump(pw, " ");
8403 } else {
8404 pw.println(" (null)");
8405 }
8406 needSep = true;
8407 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008408
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008409 if (needSep) {
8410 pw.println();
8411 }
8412 pw.println(" Historical broadcasts:");
8413 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8414 BroadcastRecord r = mBroadcastHistory[i];
8415 if (r == null) {
8416 break;
8417 }
8418 if (dumpAll) {
8419 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8420 r.dump(pw, " ");
8421 } else {
8422 if (i >= 50) {
8423 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008424 break;
8425 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008426 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008427 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008428 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008429 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008430
8431 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008432 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008433 pw.println(" Sticky broadcasts:");
8434 StringBuilder sb = new StringBuilder(128);
8435 for (Map.Entry<String, ArrayList<Intent>> ent
8436 : mStickyBroadcasts.entrySet()) {
8437 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008438 if (dumpAll) {
8439 pw.println(":");
8440 ArrayList<Intent> intents = ent.getValue();
8441 final int N = intents.size();
8442 for (int i=0; i<N; i++) {
8443 sb.setLength(0);
8444 sb.append(" Intent: ");
8445 intents.get(i).toShortString(sb, true, false);
8446 pw.println(sb.toString());
8447 Bundle bundle = intents.get(i).getExtras();
8448 if (bundle != null) {
8449 pw.print(" ");
8450 pw.println(bundle.toString());
8451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008452 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008453 } else {
8454 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008455 }
8456 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008457 needSep = true;
8458 }
8459
8460 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008461 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008462 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008463 pw.println(" mHandler:");
8464 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008465 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008466 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008467
8468 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008469 }
8470
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008471 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008472 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008473 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008474
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008475 ItemMatcher matcher = new ItemMatcher();
8476 matcher.build(args, opti);
8477
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008478 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8479 if (mServices.size() > 0) {
8480 pw.println(" Active services:");
8481 long nowReal = SystemClock.elapsedRealtime();
8482 Iterator<ServiceRecord> it = mServices.values().iterator();
8483 needSep = false;
8484 while (it.hasNext()) {
8485 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008486 if (!matcher.match(r, r.name)) {
8487 continue;
8488 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008489 if (needSep) {
8490 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008491 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008492 pw.print(" * "); pw.println(r);
8493 if (dumpAll) {
8494 r.dump(pw, " ");
8495 needSep = true;
8496 } else {
8497 pw.print(" app="); pw.println(r.app);
8498 pw.print(" created=");
8499 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8500 pw.print(" started="); pw.print(r.startRequested);
8501 pw.print(" connections="); pw.println(r.connections.size());
8502 }
8503 if (dumpClient && r.app != null && r.app.thread != null) {
8504 pw.println(" Client:");
8505 pw.flush();
8506 try {
8507 TransferPipe tp = new TransferPipe();
8508 try {
8509 r.app.thread.dumpService(
8510 tp.getWriteFd().getFileDescriptor(), r, args);
8511 tp.setBufferPrefix(" ");
8512 // Short timeout, since blocking here can
8513 // deadlock with the application.
8514 tp.go(fd, 2000);
8515 } finally {
8516 tp.kill();
8517 }
8518 } catch (IOException e) {
8519 pw.println(" Failure while dumping the service: " + e);
8520 } catch (RemoteException e) {
8521 pw.println(" Got a RemoteException while dumping the service");
8522 }
8523 needSep = true;
8524 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008525 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008526 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008528
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008529 if (mPendingServices.size() > 0) {
8530 if (needSep) pw.println(" ");
8531 pw.println(" Pending services:");
8532 for (int i=0; i<mPendingServices.size(); i++) {
8533 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008534 if (!matcher.match(r, r.name)) {
8535 continue;
8536 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008537 pw.print(" * Pending "); pw.println(r);
8538 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008539 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008540 needSep = true;
8541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008542
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008543 if (mRestartingServices.size() > 0) {
8544 if (needSep) pw.println(" ");
8545 pw.println(" Restarting services:");
8546 for (int i=0; i<mRestartingServices.size(); i++) {
8547 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008548 if (!matcher.match(r, r.name)) {
8549 continue;
8550 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008551 pw.print(" * Restarting "); pw.println(r);
8552 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008553 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008554 needSep = true;
8555 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008556
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008557 if (mStoppingServices.size() > 0) {
8558 if (needSep) pw.println(" ");
8559 pw.println(" Stopping services:");
8560 for (int i=0; i<mStoppingServices.size(); i++) {
8561 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008562 if (!matcher.match(r, r.name)) {
8563 continue;
8564 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008565 pw.print(" * Stopping "); pw.println(r);
8566 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008567 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008568 needSep = true;
8569 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008570
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008571 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008572 if (mServiceConnections.size() > 0) {
8573 if (needSep) pw.println(" ");
8574 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008575 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008576 = mServiceConnections.values().iterator();
8577 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008578 ArrayList<ConnectionRecord> r = it.next();
8579 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008580 ConnectionRecord cr = r.get(i);
8581 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8582 continue;
8583 }
8584 pw.print(" * "); pw.println(cr);
8585 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008586 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008587 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008588 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008589 }
8590 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008591
8592 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008593 }
8594
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008595 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8596 int opti, boolean dumpAll) {
8597 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008598
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008599 ItemMatcher matcher = new ItemMatcher();
8600 matcher.build(args, opti);
8601
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008602 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8603 if (mProvidersByClass.size() > 0) {
8604 if (needSep) pw.println(" ");
8605 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008606 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008607 = mProvidersByClass.entrySet().iterator();
8608 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008609 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008610 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008611 ComponentName comp = e.getKey();
8612 String cls = comp.getClassName();
8613 int end = cls.lastIndexOf('.');
8614 if (end > 0 && end < (cls.length()-2)) {
8615 cls = cls.substring(end+1);
8616 }
8617 if (!matcher.match(r, comp)) {
8618 continue;
8619 }
8620 pw.print(" * "); pw.print(cls); pw.print(" (");
8621 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008622 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008623 pw.println();
8624 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008625 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008626 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008627 if (r.app != null) {
8628 pw.println(":");
8629 pw.print(" "); pw.println(r.app);
8630 } else {
8631 pw.println();
8632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008633 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008634 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008635 needSep = true;
8636 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008637
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008638 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008639 if (mProvidersByName.size() > 0) {
8640 pw.println(" ");
8641 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008642 Iterator<Map.Entry<String, ContentProviderRecord>> it
8643 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008644 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008645 Map.Entry<String, ContentProviderRecord> e = it.next();
8646 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008647 if (!matcher.match(r, r.name)) {
8648 continue;
8649 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008650 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8651 pw.println(r);
8652 }
8653 needSep = true;
8654 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008655 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008656
8657 if (mLaunchingProviders.size() > 0) {
8658 if (needSep) pw.println(" ");
8659 pw.println(" Launching content providers:");
8660 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8661 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8662 pw.println(mLaunchingProviders.get(i));
8663 }
8664 needSep = true;
8665 }
8666
8667 if (mGrantedUriPermissions.size() > 0) {
8668 pw.println();
8669 pw.println("Granted Uri Permissions:");
8670 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8671 int uid = mGrantedUriPermissions.keyAt(i);
8672 HashMap<Uri, UriPermission> perms
8673 = mGrantedUriPermissions.valueAt(i);
8674 pw.print(" * UID "); pw.print(uid);
8675 pw.println(" holds:");
8676 for (UriPermission perm : perms.values()) {
8677 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008678 if (dumpAll) {
8679 perm.dump(pw, " ");
8680 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008681 }
8682 }
8683 needSep = true;
8684 }
8685
8686 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008687 }
8688
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008689 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8690 int opti, boolean dumpAll) {
8691 boolean needSep = false;
8692
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008693 if (this.mIntentSenderRecords.size() > 0) {
8694 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8695 Iterator<WeakReference<PendingIntentRecord>> it
8696 = mIntentSenderRecords.values().iterator();
8697 while (it.hasNext()) {
8698 WeakReference<PendingIntentRecord> ref = it.next();
8699 PendingIntentRecord rec = ref != null ? ref.get(): null;
8700 needSep = true;
8701 if (rec != null) {
8702 pw.print(" * "); pw.println(rec);
8703 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008704 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008705 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008706 } else {
8707 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008708 }
8709 }
8710 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008711
8712 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008713 }
8714
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008715 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8716 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008717 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008718 boolean needNL = false;
8719 final String innerPrefix = prefix + " ";
8720 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008721 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008722 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008723 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008724 if (needNL) {
8725 pw.println(" ");
8726 needNL = false;
8727 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008728 if (lastTask != r.task) {
8729 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008730 pw.print(prefix);
8731 pw.print(full ? "* " : " ");
8732 pw.println(lastTask);
8733 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008734 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008735 } else if (complete) {
8736 // Complete + brief == give a summary. Isn't that obvious?!?
8737 if (lastTask.intent != null) {
8738 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8739 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008740 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008741 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008742 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8743 pw.print(" #"); pw.print(i); pw.print(": ");
8744 pw.println(r);
8745 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008746 r.dump(pw, innerPrefix);
8747 } else if (complete) {
8748 // Complete + brief == give a summary. Isn't that obvious?!?
8749 pw.print(innerPrefix); pw.println(r.intent);
8750 if (r.app != null) {
8751 pw.print(innerPrefix); pw.println(r.app);
8752 }
8753 }
8754 if (client && r.app != null && r.app.thread != null) {
8755 // flush anything that is already in the PrintWriter since the thread is going
8756 // to write to the file descriptor directly
8757 pw.flush();
8758 try {
8759 TransferPipe tp = new TransferPipe();
8760 try {
8761 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8762 innerPrefix, args);
8763 // Short timeout, since blocking here can
8764 // deadlock with the application.
8765 tp.go(fd, 2000);
8766 } finally {
8767 tp.kill();
8768 }
8769 } catch (IOException e) {
8770 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8771 } catch (RemoteException e) {
8772 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8773 }
8774 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008775 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008776 }
8777 }
8778
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008779 private static String buildOomTag(String prefix, String space, int val, int base) {
8780 if (val == base) {
8781 if (space == null) return prefix;
8782 return prefix + " ";
8783 }
8784 return prefix + "+" + Integer.toString(val-base);
8785 }
8786
8787 private static final int dumpProcessList(PrintWriter pw,
8788 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008789 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008790 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008791 final int N = list.size()-1;
8792 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008793 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008794 pw.println(String.format("%s%s #%2d: %s",
8795 prefix, (r.persistent ? persistentLabel : normalLabel),
8796 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008797 if (r.persistent) {
8798 numPers++;
8799 }
8800 }
8801 return numPers;
8802 }
8803
Dianne Hackborn287952c2010-09-22 22:34:31 -07008804 private static final void dumpProcessOomList(PrintWriter pw,
8805 ActivityManagerService service, List<ProcessRecord> list,
8806 String prefix, String normalLabel, String persistentLabel,
8807 boolean inclDetails) {
8808
8809 final long curRealtime = SystemClock.elapsedRealtime();
8810 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8811 final long curUptime = SystemClock.uptimeMillis();
8812 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8813
8814 final int N = list.size()-1;
8815 for (int i=N; i>=0; i--) {
8816 ProcessRecord r = list.get(i);
8817 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008818 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8819 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8820 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8821 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
8822 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
8823 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
8824 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
8825 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
8826 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
8827 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
8828 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8829 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
8830 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8831 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
8832 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
8833 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
8834 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
8835 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
8836 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
8837 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
8838 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
8839 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008840 } else {
8841 oomAdj = Integer.toString(r.setAdj);
8842 }
8843 String schedGroup;
8844 switch (r.setSchedGroup) {
8845 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8846 schedGroup = "B";
8847 break;
8848 case Process.THREAD_GROUP_DEFAULT:
8849 schedGroup = "F";
8850 break;
8851 default:
8852 schedGroup = Integer.toString(r.setSchedGroup);
8853 break;
8854 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008855 String foreground;
8856 if (r.foregroundActivities) {
8857 foreground = "A";
8858 } else if (r.foregroundServices) {
8859 foreground = "S";
8860 } else {
8861 foreground = " ";
8862 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008863 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008864 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008865 N-i, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
8866 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008867 if (r.adjSource != null || r.adjTarget != null) {
8868 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008869 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008870 if (r.adjTarget instanceof ComponentName) {
8871 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8872 } else if (r.adjTarget != null) {
8873 pw.print(r.adjTarget.toString());
8874 } else {
8875 pw.print("{null}");
8876 }
8877 pw.print("<=");
8878 if (r.adjSource instanceof ProcessRecord) {
8879 pw.print("Proc{");
8880 pw.print(((ProcessRecord)r.adjSource).toShortString());
8881 pw.println("}");
8882 } else if (r.adjSource != null) {
8883 pw.println(r.adjSource.toString());
8884 } else {
8885 pw.println("{null}");
8886 }
8887 }
8888 if (inclDetails) {
8889 pw.print(prefix);
8890 pw.print(" ");
8891 pw.print("oom: max="); pw.print(r.maxAdj);
8892 pw.print(" hidden="); pw.print(r.hiddenAdj);
8893 pw.print(" curRaw="); pw.print(r.curRawAdj);
8894 pw.print(" setRaw="); pw.print(r.setRawAdj);
8895 pw.print(" cur="); pw.print(r.curAdj);
8896 pw.print(" set="); pw.println(r.setAdj);
8897 pw.print(prefix);
8898 pw.print(" ");
8899 pw.print("keeping="); pw.print(r.keeping);
8900 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008901 pw.print(" empty="); pw.print(r.empty);
8902 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008903
8904 if (!r.keeping) {
8905 if (r.lastWakeTime != 0) {
8906 long wtime;
8907 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8908 synchronized (stats) {
8909 wtime = stats.getProcessWakeTime(r.info.uid,
8910 r.pid, curRealtime);
8911 }
8912 long timeUsed = wtime - r.lastWakeTime;
8913 pw.print(prefix);
8914 pw.print(" ");
8915 pw.print("keep awake over ");
8916 TimeUtils.formatDuration(realtimeSince, pw);
8917 pw.print(" used ");
8918 TimeUtils.formatDuration(timeUsed, pw);
8919 pw.print(" (");
8920 pw.print((timeUsed*100)/realtimeSince);
8921 pw.println("%)");
8922 }
8923 if (r.lastCpuTime != 0) {
8924 long timeUsed = r.curCpuTime - r.lastCpuTime;
8925 pw.print(prefix);
8926 pw.print(" ");
8927 pw.print("run cpu over ");
8928 TimeUtils.formatDuration(uptimeSince, pw);
8929 pw.print(" used ");
8930 TimeUtils.formatDuration(timeUsed, pw);
8931 pw.print(" (");
8932 pw.print((timeUsed*100)/uptimeSince);
8933 pw.println("%)");
8934 }
8935 }
8936 }
8937 }
8938 }
8939
Dianne Hackbornb437e092011-08-05 17:50:29 -07008940 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008941 ArrayList<ProcessRecord> procs;
8942 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008943 if (args != null && args.length > start
8944 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008945 procs = new ArrayList<ProcessRecord>();
8946 int pid = -1;
8947 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008948 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008949 } catch (NumberFormatException e) {
8950
8951 }
8952 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8953 ProcessRecord proc = mLruProcesses.get(i);
8954 if (proc.pid == pid) {
8955 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07008956 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008957 procs.add(proc);
8958 }
8959 }
8960 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008961 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008962 return null;
8963 }
8964 } else {
8965 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8966 }
8967 }
8968 return procs;
8969 }
8970
8971 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8972 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008973 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008974 if (procs == null) {
8975 return;
8976 }
8977
8978 long uptime = SystemClock.uptimeMillis();
8979 long realtime = SystemClock.elapsedRealtime();
8980 pw.println("Applications Graphics Acceleration Info:");
8981 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8982
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008983 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8984 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008985 if (r.thread != null) {
8986 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8987 pw.flush();
8988 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008989 TransferPipe tp = new TransferPipe();
8990 try {
8991 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
8992 tp.go(fd);
8993 } finally {
8994 tp.kill();
8995 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008996 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008997 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008998 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07008999 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009000 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009001 pw.flush();
9002 }
9003 }
9004 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009005 }
9006
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009007 final static class MemItem {
9008 final String label;
9009 final long pss;
9010
9011 public MemItem(String _label, long _pss) {
9012 label = _label;
9013 pss = _pss;
9014 }
9015 }
9016
Dianne Hackbornb437e092011-08-05 17:50:29 -07009017 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9018 boolean sort) {
9019 if (sort) {
9020 Collections.sort(items, new Comparator<MemItem>() {
9021 @Override
9022 public int compare(MemItem lhs, MemItem rhs) {
9023 if (lhs.pss < rhs.pss) {
9024 return 1;
9025 } else if (lhs.pss > rhs.pss) {
9026 return -1;
9027 }
9028 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009029 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009030 });
9031 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009032
9033 for (int i=0; i<items.size(); i++) {
9034 MemItem mi = items.get(i);
9035 pw.print(prefix); pw.printf("%8d Kb: ", mi.pss); pw.println(mi.label);
9036 }
9037 }
9038
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009039 final void dumpApplicationMemoryUsage(FileDescriptor fd,
9040 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009041 boolean dumpAll = false;
9042
9043 int opti = 0;
9044 while (opti < args.length) {
9045 String opt = args[opti];
9046 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9047 break;
9048 }
9049 opti++;
9050 if ("-a".equals(opt)) {
9051 dumpAll = true;
9052 } else if ("-h".equals(opt)) {
9053 pw.println("meminfo dump options: [-a] [process]");
9054 pw.println(" -a: include all available information for each process.");
9055 pw.println("If [process] is specified it can be the name or ");
9056 pw.println("pid of a specific process to dump.");
9057 return;
9058 } else {
9059 pw.println("Unknown argument: " + opt + "; use -h for help");
9060 }
9061 }
9062
9063 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009064 if (procs == null) {
9065 return;
9066 }
9067
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009068 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009069 long uptime = SystemClock.uptimeMillis();
9070 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009071
9072 if (procs.size() == 1 || isCheckinRequest) {
9073 dumpAll = true;
9074 }
9075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009076 if (isCheckinRequest) {
9077 // short checkin version
9078 pw.println(uptime + "," + realtime);
9079 pw.flush();
9080 } else {
9081 pw.println("Applications Memory Usage (kB):");
9082 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9083 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009084
Dianne Hackbornb437e092011-08-05 17:50:29 -07009085 String[] innerArgs = new String[args.length-opti];
9086 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9087
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009088 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9089 long nativePss=0, dalvikPss=0, otherPss=0;
9090 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9091
Dianne Hackbornb437e092011-08-05 17:50:29 -07009092 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009093 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9094 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9095 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009096 };
9097 final String[] oomLabel = new String[] {
9098 "System", "Persistent", "Foreground",
9099 "Visible", "Perceptible", "Heavy Weight",
9100 "Backup", "Services", "Home", "Background"
9101 };
9102 long oomPss[] = new long[oomLabel.length];
9103
9104 long totalPss = 0;
9105
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009106 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9107 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009108 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009109 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009110 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9111 pw.flush();
9112 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009113 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009114 if (dumpAll) {
9115 try {
9116 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9117 } catch (RemoteException e) {
9118 if (!isCheckinRequest) {
9119 pw.println("Got RemoteException!");
9120 pw.flush();
9121 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009122 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009123 } else {
9124 mi = new Debug.MemoryInfo();
9125 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009126 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009127
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009128 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009129 long myTotalPss = mi.getTotalPss();
9130 totalPss += myTotalPss;
9131 procMems.add(new MemItem(r.processName + " (pid " + r.pid + ")", myTotalPss));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009132
9133 nativePss += mi.nativePss;
9134 dalvikPss += mi.dalvikPss;
9135 otherPss += mi.otherPss;
9136 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9137 long mem = mi.getOtherPss(j);
9138 miscPss[j] += mem;
9139 otherPss -= mem;
9140 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009141
9142 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9143 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9144 oomPss[oomIndex] += myTotalPss;
9145 break;
9146 }
9147 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009148 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009149 }
9150 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009151
9152 if (!isCheckinRequest && procs.size() > 1) {
9153 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9154
9155 catMems.add(new MemItem("Native", nativePss));
9156 catMems.add(new MemItem("Dalvik", dalvikPss));
9157 catMems.add(new MemItem("Unknown", otherPss));
9158 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9159 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9160 }
9161
Dianne Hackbornb437e092011-08-05 17:50:29 -07009162 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9163 for (int j=0; j<oomPss.length; j++) {
9164 if (oomPss[j] != 0) {
9165 oomMems.add(new MemItem(oomLabel[j], oomPss[j]));
9166 }
9167 }
9168
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009169 pw.println();
9170 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009171 dumpMemItems(pw, " ", procMems, true);
9172 pw.println();
9173 pw.println("Total PSS by OOM adjustment:");
9174 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009175 pw.println();
9176 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009177 dumpMemItems(pw, " ", catMems, true);
9178 pw.println();
9179 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009181 }
9182
9183 /**
9184 * Searches array of arguments for the specified string
9185 * @param args array of argument strings
9186 * @param value value to search for
9187 * @return true if the value is contained in the array
9188 */
9189 private static boolean scanArgs(String[] args, String value) {
9190 if (args != null) {
9191 for (String arg : args) {
9192 if (value.equals(arg)) {
9193 return true;
9194 }
9195 }
9196 }
9197 return false;
9198 }
9199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009200 private final void killServicesLocked(ProcessRecord app,
9201 boolean allowRestart) {
9202 // Report disconnected services.
9203 if (false) {
9204 // XXX we are letting the client link to the service for
9205 // death notifications.
9206 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009207 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009208 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009209 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009210 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009211 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009212 = r.connections.values().iterator();
9213 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009214 ArrayList<ConnectionRecord> cl = jt.next();
9215 for (int i=0; i<cl.size(); i++) {
9216 ConnectionRecord c = cl.get(i);
9217 if (c.binding.client != app) {
9218 try {
9219 //c.conn.connected(r.className, null);
9220 } catch (Exception e) {
9221 // todo: this should be asynchronous!
9222 Slog.w(TAG, "Exception thrown disconnected servce "
9223 + r.shortName
9224 + " from app " + app.processName, e);
9225 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009226 }
9227 }
9228 }
9229 }
9230 }
9231 }
9232 }
9233
9234 // Clean up any connections this application has to other services.
9235 if (app.connections.size() > 0) {
9236 Iterator<ConnectionRecord> it = app.connections.iterator();
9237 while (it.hasNext()) {
9238 ConnectionRecord r = it.next();
9239 removeConnectionLocked(r, app, null);
9240 }
9241 }
9242 app.connections.clear();
9243
9244 if (app.services.size() != 0) {
9245 // Any services running in the application need to be placed
9246 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009247 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009248 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009249 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009250 synchronized (sr.stats.getBatteryStats()) {
9251 sr.stats.stopLaunchedLocked();
9252 }
9253 sr.app = null;
9254 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009255 if (mStoppingServices.remove(sr)) {
9256 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9257 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009258
9259 boolean hasClients = sr.bindings.size() > 0;
9260 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009261 Iterator<IntentBindRecord> bindings
9262 = sr.bindings.values().iterator();
9263 while (bindings.hasNext()) {
9264 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009265 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009266 + ": shouldUnbind=" + b.hasBound);
9267 b.binder = null;
9268 b.requested = b.received = b.hasBound = false;
9269 }
9270 }
9271
Dianne Hackborn070783f2010-12-29 16:46:28 -08009272 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9273 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009274 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009275 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009276 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009277 sr.crashCount, sr.shortName, app.pid);
9278 bringDownServiceLocked(sr, true);
9279 } else if (!allowRestart) {
9280 bringDownServiceLocked(sr, true);
9281 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009282 boolean canceled = scheduleServiceRestartLocked(sr, true);
9283
9284 // Should the service remain running? Note that in the
9285 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009286 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009287 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9288 if (sr.pendingStarts.size() == 0) {
9289 sr.startRequested = false;
9290 if (!hasClients) {
9291 // Whoops, no reason to restart!
9292 bringDownServiceLocked(sr, true);
9293 }
9294 }
9295 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009296 }
9297 }
9298
9299 if (!allowRestart) {
9300 app.services.clear();
9301 }
9302 }
9303
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009304 // Make sure we have no more records on the stopping list.
9305 int i = mStoppingServices.size();
9306 while (i > 0) {
9307 i--;
9308 ServiceRecord sr = mStoppingServices.get(i);
9309 if (sr.app == app) {
9310 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009311 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009312 }
9313 }
9314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009315 app.executingServices.clear();
9316 }
9317
9318 private final void removeDyingProviderLocked(ProcessRecord proc,
9319 ContentProviderRecord cpr) {
9320 synchronized (cpr) {
9321 cpr.launchingApp = null;
9322 cpr.notifyAll();
9323 }
9324
9325 mProvidersByClass.remove(cpr.info.name);
9326 String names[] = cpr.info.authority.split(";");
9327 for (int j = 0; j < names.length; j++) {
9328 mProvidersByName.remove(names[j]);
9329 }
9330
9331 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9332 while (cit.hasNext()) {
9333 ProcessRecord capp = cit.next();
9334 if (!capp.persistent && capp.thread != null
9335 && capp.pid != 0
9336 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009337 Slog.i(TAG, "Kill " + capp.processName
9338 + " (pid " + capp.pid + "): provider " + cpr.info.name
9339 + " in dying process " + proc.processName);
9340 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9341 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009342 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009343 }
9344 }
9345
9346 mLaunchingProviders.remove(cpr);
9347 }
9348
9349 /**
9350 * Main code for cleaning up a process when it has gone away. This is
9351 * called both as a result of the process dying, or directly when stopping
9352 * a process when running in single process mode.
9353 */
9354 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009355 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009356 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009357 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009358 }
9359
Dianne Hackborn36124872009-10-08 16:22:03 -07009360 mProcessesToGc.remove(app);
9361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009362 // Dismiss any open dialogs.
9363 if (app.crashDialog != null) {
9364 app.crashDialog.dismiss();
9365 app.crashDialog = null;
9366 }
9367 if (app.anrDialog != null) {
9368 app.anrDialog.dismiss();
9369 app.anrDialog = null;
9370 }
9371 if (app.waitDialog != null) {
9372 app.waitDialog.dismiss();
9373 app.waitDialog = null;
9374 }
9375
9376 app.crashing = false;
9377 app.notResponding = false;
9378
9379 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009380 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009381 app.thread = null;
9382 app.forcingToForeground = null;
9383 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009384 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009385 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009386 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009387
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009388 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009389
9390 boolean restart = false;
9391
9392 int NL = mLaunchingProviders.size();
9393
9394 // Remove published content providers.
9395 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009396 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009397 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009398 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009399 cpr.provider = null;
9400 cpr.app = null;
9401
9402 // See if someone is waiting for this provider... in which
9403 // case we don't remove it, but just let it restart.
9404 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009405 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009406 for (; i<NL; i++) {
9407 if (mLaunchingProviders.get(i) == cpr) {
9408 restart = true;
9409 break;
9410 }
9411 }
9412 } else {
9413 i = NL;
9414 }
9415
9416 if (i >= NL) {
9417 removeDyingProviderLocked(app, cpr);
9418 NL = mLaunchingProviders.size();
9419 }
9420 }
9421 app.pubProviders.clear();
9422 }
9423
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009424 // Take care of any launching providers waiting for this process.
9425 if (checkAppInLaunchingProvidersLocked(app, false)) {
9426 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009427 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009429 // Unregister from connected content providers.
9430 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009431 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009432 while (it.hasNext()) {
9433 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9434 cpr.clients.remove(app);
9435 }
9436 app.conProviders.clear();
9437 }
9438
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009439 // At this point there may be remaining entries in mLaunchingProviders
9440 // where we were the only one waiting, so they are no longer of use.
9441 // Look for these and clean up if found.
9442 // XXX Commented out for now. Trying to figure out a way to reproduce
9443 // the actual situation to identify what is actually going on.
9444 if (false) {
9445 for (int i=0; i<NL; i++) {
9446 ContentProviderRecord cpr = (ContentProviderRecord)
9447 mLaunchingProviders.get(i);
9448 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9449 synchronized (cpr) {
9450 cpr.launchingApp = null;
9451 cpr.notifyAll();
9452 }
9453 }
9454 }
9455 }
9456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009457 skipCurrentReceiverLocked(app);
9458
9459 // Unregister any receivers.
9460 if (app.receivers.size() > 0) {
9461 Iterator<ReceiverList> it = app.receivers.iterator();
9462 while (it.hasNext()) {
9463 removeReceiverLocked(it.next());
9464 }
9465 app.receivers.clear();
9466 }
9467
Christopher Tate181fafa2009-05-14 11:12:14 -07009468 // If the app is undergoing backup, tell the backup manager about it
9469 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009470 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009471 try {
9472 IBackupManager bm = IBackupManager.Stub.asInterface(
9473 ServiceManager.getService(Context.BACKUP_SERVICE));
9474 bm.agentDisconnected(app.info.packageName);
9475 } catch (RemoteException e) {
9476 // can't happen; backup manager is local
9477 }
9478 }
9479
Jeff Sharkey287bd832011-05-28 19:36:26 -07009480 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009482 // If the caller is restarting this app, then leave it in its
9483 // current lists and let the caller take care of it.
9484 if (restarting) {
9485 return;
9486 }
9487
9488 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009489 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009490 "Removing non-persistent process during cleanup: " + app);
9491 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009492 if (mHeavyWeightProcess == app) {
9493 mHeavyWeightProcess = null;
9494 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009496 } else if (!app.removed) {
9497 // This app is persistent, so we need to keep its record around.
9498 // If it is not already on the pending app list, add it there
9499 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009500 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9501 mPersistentStartingProcesses.add(app);
9502 restart = true;
9503 }
9504 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009505 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9506 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009507 mProcessesOnHold.remove(app);
9508
The Android Open Source Project4df24232009-03-05 14:34:35 -08009509 if (app == mHomeProcess) {
9510 mHomeProcess = null;
9511 }
9512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009513 if (restart) {
9514 // We have components that still need to be running in the
9515 // process, so re-launch it.
9516 mProcessNames.put(app.processName, app.info.uid, app);
9517 startProcessLocked(app, "restart", app.processName);
9518 } else if (app.pid > 0 && app.pid != MY_PID) {
9519 // Goodbye!
9520 synchronized (mPidsSelfLocked) {
9521 mPidsSelfLocked.remove(app.pid);
9522 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9523 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009524 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009525 }
9526 }
9527
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009528 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9529 // Look through the content providers we are waiting to have launched,
9530 // and if any run in this process then either schedule a restart of
9531 // the process or kill the client waiting for it if this process has
9532 // gone bad.
9533 int NL = mLaunchingProviders.size();
9534 boolean restart = false;
9535 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009536 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009537 if (cpr.launchingApp == app) {
9538 if (!alwaysBad && !app.bad) {
9539 restart = true;
9540 } else {
9541 removeDyingProviderLocked(app, cpr);
9542 NL = mLaunchingProviders.size();
9543 }
9544 }
9545 }
9546 return restart;
9547 }
9548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009549 // =========================================================
9550 // SERVICES
9551 // =========================================================
9552
9553 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9554 ActivityManager.RunningServiceInfo info =
9555 new ActivityManager.RunningServiceInfo();
9556 info.service = r.name;
9557 if (r.app != null) {
9558 info.pid = r.app.pid;
9559 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009560 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009561 info.process = r.processName;
9562 info.foreground = r.isForeground;
9563 info.activeSince = r.createTime;
9564 info.started = r.startRequested;
9565 info.clientCount = r.connections.size();
9566 info.crashCount = r.crashCount;
9567 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009568 if (r.isForeground) {
9569 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9570 }
9571 if (r.startRequested) {
9572 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9573 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009574 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009575 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9576 }
9577 if (r.app != null && r.app.persistent) {
9578 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9579 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009580
9581 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9582 for (int i=0; i<connl.size(); i++) {
9583 ConnectionRecord conn = connl.get(i);
9584 if (conn.clientLabel != 0) {
9585 info.clientPackage = conn.binding.client.info.packageName;
9586 info.clientLabel = conn.clientLabel;
9587 return info;
9588 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009589 }
9590 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009591 return info;
9592 }
9593
9594 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9595 int flags) {
9596 synchronized (this) {
9597 ArrayList<ActivityManager.RunningServiceInfo> res
9598 = new ArrayList<ActivityManager.RunningServiceInfo>();
9599
9600 if (mServices.size() > 0) {
9601 Iterator<ServiceRecord> it = mServices.values().iterator();
9602 while (it.hasNext() && res.size() < maxNum) {
9603 res.add(makeRunningServiceInfoLocked(it.next()));
9604 }
9605 }
9606
9607 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9608 ServiceRecord r = mRestartingServices.get(i);
9609 ActivityManager.RunningServiceInfo info =
9610 makeRunningServiceInfoLocked(r);
9611 info.restarting = r.nextRestartTime;
9612 res.add(info);
9613 }
9614
9615 return res;
9616 }
9617 }
9618
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009619 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9620 synchronized (this) {
9621 ServiceRecord r = mServices.get(name);
9622 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009623 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9624 for (int i=0; i<conn.size(); i++) {
9625 if (conn.get(i).clientIntent != null) {
9626 return conn.get(i).clientIntent;
9627 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009628 }
9629 }
9630 }
9631 }
9632 return null;
9633 }
9634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009635 private final ServiceRecord findServiceLocked(ComponentName name,
9636 IBinder token) {
9637 ServiceRecord r = mServices.get(name);
9638 return r == token ? r : null;
9639 }
9640
9641 private final class ServiceLookupResult {
9642 final ServiceRecord record;
9643 final String permission;
9644
9645 ServiceLookupResult(ServiceRecord _record, String _permission) {
9646 record = _record;
9647 permission = _permission;
9648 }
9649 };
9650
9651 private ServiceLookupResult findServiceLocked(Intent service,
9652 String resolvedType) {
9653 ServiceRecord r = null;
9654 if (service.getComponent() != null) {
9655 r = mServices.get(service.getComponent());
9656 }
9657 if (r == null) {
9658 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9659 r = mServicesByIntent.get(filter);
9660 }
9661
9662 if (r == null) {
9663 try {
9664 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009665 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009666 service, resolvedType, 0);
9667 ServiceInfo sInfo =
9668 rInfo != null ? rInfo.serviceInfo : null;
9669 if (sInfo == null) {
9670 return null;
9671 }
9672
9673 ComponentName name = new ComponentName(
9674 sInfo.applicationInfo.packageName, sInfo.name);
9675 r = mServices.get(name);
9676 } catch (RemoteException ex) {
9677 // pm is in same process, this will never happen.
9678 }
9679 }
9680 if (r != null) {
9681 int callingPid = Binder.getCallingPid();
9682 int callingUid = Binder.getCallingUid();
9683 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009684 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009686 if (!r.exported) {
9687 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9688 + " from pid=" + callingPid
9689 + ", uid=" + callingUid
9690 + " that is not exported from uid " + r.appInfo.uid);
9691 return new ServiceLookupResult(null, "not exported from uid "
9692 + r.appInfo.uid);
9693 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009694 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009695 + " from pid=" + callingPid
9696 + ", uid=" + callingUid
9697 + " requires " + r.permission);
9698 return new ServiceLookupResult(null, r.permission);
9699 }
9700 return new ServiceLookupResult(r, null);
9701 }
9702 return null;
9703 }
9704
9705 private class ServiceRestarter implements Runnable {
9706 private ServiceRecord mService;
9707
9708 void setService(ServiceRecord service) {
9709 mService = service;
9710 }
9711
9712 public void run() {
9713 synchronized(ActivityManagerService.this) {
9714 performServiceRestartLocked(mService);
9715 }
9716 }
9717 }
9718
9719 private ServiceLookupResult retrieveServiceLocked(Intent service,
9720 String resolvedType, int callingPid, int callingUid) {
9721 ServiceRecord r = null;
9722 if (service.getComponent() != null) {
9723 r = mServices.get(service.getComponent());
9724 }
9725 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9726 r = mServicesByIntent.get(filter);
9727 if (r == null) {
9728 try {
9729 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009730 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009731 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009732 ServiceInfo sInfo =
9733 rInfo != null ? rInfo.serviceInfo : null;
9734 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009735 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009736 ": not found");
9737 return null;
9738 }
9739
9740 ComponentName name = new ComponentName(
9741 sInfo.applicationInfo.packageName, sInfo.name);
9742 r = mServices.get(name);
9743 if (r == null) {
9744 filter = new Intent.FilterComparison(service.cloneFilter());
9745 ServiceRestarter res = new ServiceRestarter();
9746 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9747 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9748 synchronized (stats) {
9749 ss = stats.getServiceStatsLocked(
9750 sInfo.applicationInfo.uid, sInfo.packageName,
9751 sInfo.name);
9752 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009753 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009754 res.setService(r);
9755 mServices.put(name, r);
9756 mServicesByIntent.put(filter, r);
9757
9758 // Make sure this component isn't in the pending list.
9759 int N = mPendingServices.size();
9760 for (int i=0; i<N; i++) {
9761 ServiceRecord pr = mPendingServices.get(i);
9762 if (pr.name.equals(name)) {
9763 mPendingServices.remove(i);
9764 i--;
9765 N--;
9766 }
9767 }
9768 }
9769 } catch (RemoteException ex) {
9770 // pm is in same process, this will never happen.
9771 }
9772 }
9773 if (r != null) {
9774 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009775 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009776 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009777 if (!r.exported) {
9778 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9779 + " from pid=" + callingPid
9780 + ", uid=" + callingUid
9781 + " that is not exported from uid " + r.appInfo.uid);
9782 return new ServiceLookupResult(null, "not exported from uid "
9783 + r.appInfo.uid);
9784 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009785 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009786 + " from pid=" + callingPid
9787 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009788 + " requires " + r.permission);
9789 return new ServiceLookupResult(null, r.permission);
9790 }
9791 return new ServiceLookupResult(r, null);
9792 }
9793 return null;
9794 }
9795
Dianne Hackborn287952c2010-09-22 22:34:31 -07009796 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9797 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9798 + why + " of " + r + " in app " + r.app);
9799 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9800 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009801 long now = SystemClock.uptimeMillis();
9802 if (r.executeNesting == 0 && r.app != null) {
9803 if (r.app.executingServices.size() == 0) {
9804 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9805 msg.obj = r.app;
9806 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9807 }
9808 r.app.executingServices.add(r);
9809 }
9810 r.executeNesting++;
9811 r.executingStart = now;
9812 }
9813
9814 private final void sendServiceArgsLocked(ServiceRecord r,
9815 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009816 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009817 if (N == 0) {
9818 return;
9819 }
9820
Dianne Hackborn39792d22010-08-19 18:01:52 -07009821 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009822 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009823 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009824 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9825 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009826 if (si.intent == null && N > 1) {
9827 // If somehow we got a dummy null intent in the middle,
9828 // then skip it. DO NOT skip a null intent when it is
9829 // the only one in the list -- this is to support the
9830 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009831 continue;
9832 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009833 si.deliveredTime = SystemClock.uptimeMillis();
9834 r.deliveredStarts.add(si);
9835 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009836 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009837 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009838 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009839 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009840 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009841 if (!oomAdjusted) {
9842 oomAdjusted = true;
9843 updateOomAdjLocked(r.app);
9844 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009845 int flags = 0;
9846 if (si.deliveryCount > 0) {
9847 flags |= Service.START_FLAG_RETRY;
9848 }
9849 if (si.doneExecutingCount > 0) {
9850 flags |= Service.START_FLAG_REDELIVERY;
9851 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009852 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009853 } catch (RemoteException e) {
9854 // Remote process gone... we'll let the normal cleanup take
9855 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009856 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009857 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009858 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009859 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009860 break;
9861 }
9862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009863 }
9864
9865 private final boolean requestServiceBindingLocked(ServiceRecord r,
9866 IntentBindRecord i, boolean rebind) {
9867 if (r.app == null || r.app.thread == null) {
9868 // If service is not currently running, can't yet bind.
9869 return false;
9870 }
9871 if ((!i.requested || rebind) && i.apps.size() > 0) {
9872 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009873 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009874 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9875 if (!rebind) {
9876 i.requested = true;
9877 }
9878 i.hasBound = true;
9879 i.doRebind = false;
9880 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009881 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009882 return false;
9883 }
9884 }
9885 return true;
9886 }
9887
9888 private final void requestServiceBindingsLocked(ServiceRecord r) {
9889 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9890 while (bindings.hasNext()) {
9891 IntentBindRecord i = bindings.next();
9892 if (!requestServiceBindingLocked(r, i, false)) {
9893 break;
9894 }
9895 }
9896 }
9897
9898 private final void realStartServiceLocked(ServiceRecord r,
9899 ProcessRecord app) throws RemoteException {
9900 if (app.thread == null) {
9901 throw new RemoteException();
9902 }
9903
9904 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009905 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009906
9907 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009908 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009909 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009910
9911 boolean created = false;
9912 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009913 mStringBuilder.setLength(0);
9914 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009915 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009916 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009917 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009918 synchronized (r.stats.getBatteryStats()) {
9919 r.stats.startLaunchedLocked();
9920 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009921 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009922 app.thread.scheduleCreateService(r, r.serviceInfo,
9923 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009924 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009925 created = true;
9926 } finally {
9927 if (!created) {
9928 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009929 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009930 }
9931 }
9932
9933 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009934
9935 // If the service is in the started state, and there are no
9936 // pending arguments, then fake up one so its onStartCommand() will
9937 // be called.
9938 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009939 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9940 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009941 }
9942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009943 sendServiceArgsLocked(r, true);
9944 }
9945
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009946 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9947 boolean allowCancel) {
9948 boolean canceled = false;
9949
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009950 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009951 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009952 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009953
Dianne Hackborn070783f2010-12-29 16:46:28 -08009954 if ((r.serviceInfo.applicationInfo.flags
9955 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9956 minDuration /= 4;
9957 }
9958
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009959 // Any delivered but not yet finished starts should be put back
9960 // on the pending list.
9961 final int N = r.deliveredStarts.size();
9962 if (N > 0) {
9963 for (int i=N-1; i>=0; i--) {
9964 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009965 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009966 if (si.intent == null) {
9967 // We'll generate this again if needed.
9968 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9969 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9970 r.pendingStarts.add(0, si);
9971 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9972 dur *= 2;
9973 if (minDuration < dur) minDuration = dur;
9974 if (resetTime < dur) resetTime = dur;
9975 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009976 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009977 + r.name);
9978 canceled = true;
9979 }
9980 }
9981 r.deliveredStarts.clear();
9982 }
9983
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009984 r.totalRestartCount++;
9985 if (r.restartDelay == 0) {
9986 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009987 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009988 } else {
9989 // If it has been a "reasonably long time" since the service
9990 // was started, then reset our restart duration back to
9991 // the beginning, so we don't infinitely increase the duration
9992 // on a service that just occasionally gets killed (which is
9993 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009994 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009995 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009996 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009997 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009998 if ((r.serviceInfo.applicationInfo.flags
9999 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10000 // Services in peristent processes will restart much more
10001 // quickly, since they are pretty important. (Think SystemUI).
10002 r.restartDelay += minDuration/2;
10003 } else {
10004 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10005 if (r.restartDelay < minDuration) {
10006 r.restartDelay = minDuration;
10007 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010008 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010009 }
10010 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010011
10012 r.nextRestartTime = now + r.restartDelay;
10013
10014 // Make sure that we don't end up restarting a bunch of services
10015 // all at the same time.
10016 boolean repeat;
10017 do {
10018 repeat = false;
10019 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10020 ServiceRecord r2 = mRestartingServices.get(i);
10021 if (r2 != r && r.nextRestartTime
10022 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10023 && r.nextRestartTime
10024 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10025 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10026 r.restartDelay = r.nextRestartTime - now;
10027 repeat = true;
10028 break;
10029 }
10030 }
10031 } while (repeat);
10032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010033 if (!mRestartingServices.contains(r)) {
10034 mRestartingServices.add(r);
10035 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010036
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010037 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010039 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010040 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010041 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010042 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010043 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010044 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010045 r.shortName, r.restartDelay);
10046
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010047 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010048 }
10049
10050 final void performServiceRestartLocked(ServiceRecord r) {
10051 if (!mRestartingServices.contains(r)) {
10052 return;
10053 }
10054 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10055 }
10056
10057 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10058 if (r.restartDelay == 0) {
10059 return false;
10060 }
10061 r.resetRestartCounter();
10062 mRestartingServices.remove(r);
10063 mHandler.removeCallbacks(r.restarter);
10064 return true;
10065 }
10066
10067 private final boolean bringUpServiceLocked(ServiceRecord r,
10068 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010069 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010070 //r.dump(" ");
10071
Dianne Hackborn36124872009-10-08 16:22:03 -070010072 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010073 sendServiceArgsLocked(r, false);
10074 return true;
10075 }
10076
10077 if (!whileRestarting && r.restartDelay > 0) {
10078 // If waiting for a restart, then do nothing.
10079 return true;
10080 }
10081
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010082 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010083
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010084 // We are now bringing the service up, so no longer in the
10085 // restarting state.
10086 mRestartingServices.remove(r);
10087
Dianne Hackborne7f97212011-02-24 14:40:20 -080010088 // Service is now being launched, its package can't be stopped.
10089 try {
10090 AppGlobals.getPackageManager().setPackageStoppedState(
10091 r.packageName, false);
10092 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010093 } catch (IllegalArgumentException e) {
10094 Slog.w(TAG, "Failed trying to unstop package "
10095 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010096 }
10097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010098 final String appName = r.processName;
10099 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10100 if (app != null && app.thread != null) {
10101 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010102 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010103 realStartServiceLocked(r, app);
10104 return true;
10105 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010106 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010107 }
10108
10109 // If a dead object exception was thrown -- fall through to
10110 // restart the application.
10111 }
10112
Dianne Hackborn36124872009-10-08 16:22:03 -070010113 // Not running -- get it started, and enqueue this service record
10114 // to be executed when the app comes up.
10115 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10116 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010117 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010118 + r.appInfo.packageName + "/"
10119 + r.appInfo.uid + " for service "
10120 + r.intent.getIntent() + ": process is bad");
10121 bringDownServiceLocked(r, true);
10122 return false;
10123 }
10124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010125 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010126 mPendingServices.add(r);
10127 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010129 return true;
10130 }
10131
10132 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010133 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010134 //r.dump(" ");
10135
10136 // Does it still need to run?
10137 if (!force && r.startRequested) {
10138 return;
10139 }
10140 if (r.connections.size() > 0) {
10141 if (!force) {
10142 // XXX should probably keep a count of the number of auto-create
10143 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010144 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010145 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010146 ArrayList<ConnectionRecord> cr = it.next();
10147 for (int i=0; i<cr.size(); i++) {
10148 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10149 return;
10150 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010151 }
10152 }
10153 }
10154
10155 // Report to all of the connections that the service is no longer
10156 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010157 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010158 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010159 ArrayList<ConnectionRecord> c = it.next();
10160 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010161 ConnectionRecord cr = c.get(i);
10162 // There is still a connection to the service that is
10163 // being brought down. Mark it as dead.
10164 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010165 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010166 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010167 } catch (Exception e) {
10168 Slog.w(TAG, "Failure disconnecting service " + r.name +
10169 " to connection " + c.get(i).conn.asBinder() +
10170 " (in " + c.get(i).binding.client.processName + ")", e);
10171 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010172 }
10173 }
10174 }
10175
10176 // Tell the service that it has been unbound.
10177 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10178 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10179 while (it.hasNext()) {
10180 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010181 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010182 + ": hasBound=" + ibr.hasBound);
10183 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10184 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010185 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010186 updateOomAdjLocked(r.app);
10187 ibr.hasBound = false;
10188 r.app.thread.scheduleUnbindService(r,
10189 ibr.intent.getIntent());
10190 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010191 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010192 + r.shortName, e);
10193 serviceDoneExecutingLocked(r, true);
10194 }
10195 }
10196 }
10197 }
10198
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010199 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010200 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010201 System.identityHashCode(r), r.shortName,
10202 (r.app != null) ? r.app.pid : -1);
10203
10204 mServices.remove(r.name);
10205 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010206 r.totalRestartCount = 0;
10207 unscheduleServiceRestartLocked(r);
10208
10209 // Also make sure it is not on the pending list.
10210 int N = mPendingServices.size();
10211 for (int i=0; i<N; i++) {
10212 if (mPendingServices.get(i) == r) {
10213 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010214 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010215 i--;
10216 N--;
10217 }
10218 }
10219
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010220 r.cancelNotification();
10221 r.isForeground = false;
10222 r.foregroundId = 0;
10223 r.foregroundNoti = null;
10224
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010225 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010226 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010227 r.pendingStarts.clear();
10228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010229 if (r.app != null) {
10230 synchronized (r.stats.getBatteryStats()) {
10231 r.stats.stopLaunchedLocked();
10232 }
10233 r.app.services.remove(r);
10234 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010235 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010236 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010237 mStoppingServices.add(r);
10238 updateOomAdjLocked(r.app);
10239 r.app.thread.scheduleStopService(r);
10240 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010241 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010242 + r.shortName, e);
10243 serviceDoneExecutingLocked(r, true);
10244 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010245 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010246 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010247 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010248 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010249 }
10250 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010251 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010252 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010253 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010254
10255 if (r.bindings.size() > 0) {
10256 r.bindings.clear();
10257 }
10258
10259 if (r.restarter instanceof ServiceRestarter) {
10260 ((ServiceRestarter)r.restarter).setService(null);
10261 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010262 }
10263
10264 ComponentName startServiceLocked(IApplicationThread caller,
10265 Intent service, String resolvedType,
10266 int callingPid, int callingUid) {
10267 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010268 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010269 + " type=" + resolvedType + " args=" + service.getExtras());
10270
10271 if (caller != null) {
10272 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10273 if (callerApp == null) {
10274 throw new SecurityException(
10275 "Unable to find app for caller " + caller
10276 + " (pid=" + Binder.getCallingPid()
10277 + ") when starting service " + service);
10278 }
10279 }
10280
10281 ServiceLookupResult res =
10282 retrieveServiceLocked(service, resolvedType,
10283 callingPid, callingUid);
10284 if (res == null) {
10285 return null;
10286 }
10287 if (res.record == null) {
10288 return new ComponentName("!", res.permission != null
10289 ? res.permission : "private to package");
10290 }
10291 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010292 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10293 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010294 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010295 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010296 }
10297 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010298 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010299 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010300 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010301 r.lastActivity = SystemClock.uptimeMillis();
10302 synchronized (r.stats.getBatteryStats()) {
10303 r.stats.startRunningLocked();
10304 }
10305 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10306 return new ComponentName("!", "Service process is bad");
10307 }
10308 return r.name;
10309 }
10310 }
10311
10312 public ComponentName startService(IApplicationThread caller, Intent service,
10313 String resolvedType) {
10314 // Refuse possible leaked file descriptors
10315 if (service != null && service.hasFileDescriptors() == true) {
10316 throw new IllegalArgumentException("File descriptors passed in Intent");
10317 }
10318
10319 synchronized(this) {
10320 final int callingPid = Binder.getCallingPid();
10321 final int callingUid = Binder.getCallingUid();
10322 final long origId = Binder.clearCallingIdentity();
10323 ComponentName res = startServiceLocked(caller, service,
10324 resolvedType, callingPid, callingUid);
10325 Binder.restoreCallingIdentity(origId);
10326 return res;
10327 }
10328 }
10329
10330 ComponentName startServiceInPackage(int uid,
10331 Intent service, String resolvedType) {
10332 synchronized(this) {
10333 final long origId = Binder.clearCallingIdentity();
10334 ComponentName res = startServiceLocked(null, service,
10335 resolvedType, -1, uid);
10336 Binder.restoreCallingIdentity(origId);
10337 return res;
10338 }
10339 }
10340
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010341 private void stopServiceLocked(ServiceRecord service) {
10342 synchronized (service.stats.getBatteryStats()) {
10343 service.stats.stopRunningLocked();
10344 }
10345 service.startRequested = false;
10346 service.callStart = false;
10347 bringDownServiceLocked(service, false);
10348 }
10349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010350 public int stopService(IApplicationThread caller, Intent service,
10351 String resolvedType) {
10352 // Refuse possible leaked file descriptors
10353 if (service != null && service.hasFileDescriptors() == true) {
10354 throw new IllegalArgumentException("File descriptors passed in Intent");
10355 }
10356
10357 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010358 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010359 + " type=" + resolvedType);
10360
10361 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10362 if (caller != null && callerApp == null) {
10363 throw new SecurityException(
10364 "Unable to find app for caller " + caller
10365 + " (pid=" + Binder.getCallingPid()
10366 + ") when stopping service " + service);
10367 }
10368
10369 // If this service is active, make sure it is stopped.
10370 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10371 if (r != null) {
10372 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010373 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010374 try {
10375 stopServiceLocked(r.record);
10376 } finally {
10377 Binder.restoreCallingIdentity(origId);
10378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010379 return 1;
10380 }
10381 return -1;
10382 }
10383 }
10384
10385 return 0;
10386 }
10387
10388 public IBinder peekService(Intent service, String resolvedType) {
10389 // Refuse possible leaked file descriptors
10390 if (service != null && service.hasFileDescriptors() == true) {
10391 throw new IllegalArgumentException("File descriptors passed in Intent");
10392 }
10393
10394 IBinder ret = null;
10395
10396 synchronized(this) {
10397 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10398
10399 if (r != null) {
10400 // r.record is null if findServiceLocked() failed the caller permission check
10401 if (r.record == null) {
10402 throw new SecurityException(
10403 "Permission Denial: Accessing service " + r.record.name
10404 + " from pid=" + Binder.getCallingPid()
10405 + ", uid=" + Binder.getCallingUid()
10406 + " requires " + r.permission);
10407 }
10408 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10409 if (ib != null) {
10410 ret = ib.binder;
10411 }
10412 }
10413 }
10414
10415 return ret;
10416 }
10417
10418 public boolean stopServiceToken(ComponentName className, IBinder token,
10419 int startId) {
10420 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010421 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010422 + " " + token + " startId=" + startId);
10423 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010424 if (r != null) {
10425 if (startId >= 0) {
10426 // Asked to only stop if done with all work. Note that
10427 // to avoid leaks, we will take this as dropping all
10428 // start items up to and including this one.
10429 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10430 if (si != null) {
10431 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010432 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10433 cur.removeUriPermissionsLocked();
10434 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010435 break;
10436 }
10437 }
10438 }
10439
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010440 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010441 return false;
10442 }
10443
10444 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010445 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010446 + " is last, but have " + r.deliveredStarts.size()
10447 + " remaining args");
10448 }
10449 }
10450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010451 synchronized (r.stats.getBatteryStats()) {
10452 r.stats.stopRunningLocked();
10453 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010454 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010455 }
10456 final long origId = Binder.clearCallingIdentity();
10457 bringDownServiceLocked(r, false);
10458 Binder.restoreCallingIdentity(origId);
10459 return true;
10460 }
10461 }
10462 return false;
10463 }
10464
10465 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010466 int id, Notification notification, boolean removeNotification) {
10467 final long origId = Binder.clearCallingIdentity();
10468 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010469 synchronized(this) {
10470 ServiceRecord r = findServiceLocked(className, token);
10471 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010472 if (id != 0) {
10473 if (notification == null) {
10474 throw new IllegalArgumentException("null notification");
10475 }
10476 if (r.foregroundId != id) {
10477 r.cancelNotification();
10478 r.foregroundId = id;
10479 }
10480 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10481 r.foregroundNoti = notification;
10482 r.isForeground = true;
10483 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010484 if (r.app != null) {
10485 updateServiceForegroundLocked(r.app, true);
10486 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010487 } else {
10488 if (r.isForeground) {
10489 r.isForeground = false;
10490 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010491 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010492 updateServiceForegroundLocked(r.app, true);
10493 }
10494 }
10495 if (removeNotification) {
10496 r.cancelNotification();
10497 r.foregroundId = 0;
10498 r.foregroundNoti = null;
10499 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010500 }
10501 }
10502 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010503 } finally {
10504 Binder.restoreCallingIdentity(origId);
10505 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010506 }
10507
10508 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10509 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010510 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010511 if (sr.isForeground) {
10512 anyForeground = true;
10513 break;
10514 }
10515 }
10516 if (anyForeground != proc.foregroundServices) {
10517 proc.foregroundServices = anyForeground;
10518 if (oomAdj) {
10519 updateOomAdjLocked();
10520 }
10521 }
10522 }
10523
10524 public int bindService(IApplicationThread caller, IBinder token,
10525 Intent service, String resolvedType,
10526 IServiceConnection connection, int flags) {
10527 // Refuse possible leaked file descriptors
10528 if (service != null && service.hasFileDescriptors() == true) {
10529 throw new IllegalArgumentException("File descriptors passed in Intent");
10530 }
10531
10532 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010533 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010534 + " type=" + resolvedType + " conn=" + connection.asBinder()
10535 + " flags=0x" + Integer.toHexString(flags));
10536 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10537 if (callerApp == null) {
10538 throw new SecurityException(
10539 "Unable to find app for caller " + caller
10540 + " (pid=" + Binder.getCallingPid()
10541 + ") when binding service " + service);
10542 }
10543
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010544 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010545 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010546 activity = mMainStack.isInStackLocked(token);
10547 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010548 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010549 return 0;
10550 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010551 }
10552
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010553 int clientLabel = 0;
10554 PendingIntent clientIntent = null;
10555
10556 if (callerApp.info.uid == Process.SYSTEM_UID) {
10557 // Hacky kind of thing -- allow system stuff to tell us
10558 // what they are, so we can report this elsewhere for
10559 // others to know why certain services are running.
10560 try {
10561 clientIntent = (PendingIntent)service.getParcelableExtra(
10562 Intent.EXTRA_CLIENT_INTENT);
10563 } catch (RuntimeException e) {
10564 }
10565 if (clientIntent != null) {
10566 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10567 if (clientLabel != 0) {
10568 // There are no useful extras in the intent, trash them.
10569 // System code calling with this stuff just needs to know
10570 // this will happen.
10571 service = service.cloneFilter();
10572 }
10573 }
10574 }
10575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010576 ServiceLookupResult res =
10577 retrieveServiceLocked(service, resolvedType,
10578 Binder.getCallingPid(), Binder.getCallingUid());
10579 if (res == null) {
10580 return 0;
10581 }
10582 if (res.record == null) {
10583 return -1;
10584 }
10585 ServiceRecord s = res.record;
10586
10587 final long origId = Binder.clearCallingIdentity();
10588
10589 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010590 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010591 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010592 }
10593
10594 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10595 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010596 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010597
10598 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010599 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10600 if (clist == null) {
10601 clist = new ArrayList<ConnectionRecord>();
10602 s.connections.put(binder, clist);
10603 }
10604 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010605 b.connections.add(c);
10606 if (activity != null) {
10607 if (activity.connections == null) {
10608 activity.connections = new HashSet<ConnectionRecord>();
10609 }
10610 activity.connections.add(c);
10611 }
10612 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010613 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10614 b.client.hasAboveClient = true;
10615 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010616 clist = mServiceConnections.get(binder);
10617 if (clist == null) {
10618 clist = new ArrayList<ConnectionRecord>();
10619 mServiceConnections.put(binder, clist);
10620 }
10621 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010622
10623 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10624 s.lastActivity = SystemClock.uptimeMillis();
10625 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10626 return 0;
10627 }
10628 }
10629
10630 if (s.app != null) {
10631 // This could have made the service more important.
10632 updateOomAdjLocked(s.app);
10633 }
10634
Joe Onorato8a9b2202010-02-26 18:56:32 -080010635 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010636 + ": received=" + b.intent.received
10637 + " apps=" + b.intent.apps.size()
10638 + " doRebind=" + b.intent.doRebind);
10639
10640 if (s.app != null && b.intent.received) {
10641 // Service is already running, so we can immediately
10642 // publish the connection.
10643 try {
10644 c.conn.connected(s.name, b.intent.binder);
10645 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010646 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010647 + " to connection " + c.conn.asBinder()
10648 + " (in " + c.binding.client.processName + ")", e);
10649 }
10650
10651 // If this is the first app connected back to this binding,
10652 // and the service had previously asked to be told when
10653 // rebound, then do so.
10654 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10655 requestServiceBindingLocked(s, b.intent, true);
10656 }
10657 } else if (!b.intent.requested) {
10658 requestServiceBindingLocked(s, b.intent, false);
10659 }
10660
10661 Binder.restoreCallingIdentity(origId);
10662 }
10663
10664 return 1;
10665 }
10666
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010667 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010668 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010669 IBinder binder = c.conn.asBinder();
10670 AppBindRecord b = c.binding;
10671 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010672 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10673 if (clist != null) {
10674 clist.remove(c);
10675 if (clist.size() == 0) {
10676 s.connections.remove(binder);
10677 }
10678 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010679 b.connections.remove(c);
10680 if (c.activity != null && c.activity != skipAct) {
10681 if (c.activity.connections != null) {
10682 c.activity.connections.remove(c);
10683 }
10684 }
10685 if (b.client != skipApp) {
10686 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010687 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10688 b.client.updateHasAboveClientLocked();
10689 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010690 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010691 clist = mServiceConnections.get(binder);
10692 if (clist != null) {
10693 clist.remove(c);
10694 if (clist.size() == 0) {
10695 mServiceConnections.remove(binder);
10696 }
10697 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010698
10699 if (b.connections.size() == 0) {
10700 b.intent.apps.remove(b.client);
10701 }
10702
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010703 if (!c.serviceDead) {
10704 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10705 + ": shouldUnbind=" + b.intent.hasBound);
10706 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10707 && b.intent.hasBound) {
10708 try {
10709 bumpServiceExecutingLocked(s, "unbind");
10710 updateOomAdjLocked(s.app);
10711 b.intent.hasBound = false;
10712 // Assume the client doesn't want to know about a rebind;
10713 // we will deal with that later if it asks for one.
10714 b.intent.doRebind = false;
10715 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10716 } catch (Exception e) {
10717 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10718 serviceDoneExecutingLocked(s, true);
10719 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010720 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010721
10722 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10723 bringDownServiceLocked(s, false);
10724 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010725 }
10726 }
10727
10728 public boolean unbindService(IServiceConnection connection) {
10729 synchronized (this) {
10730 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010731 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010732 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10733 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010734 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010735 + connection.asBinder());
10736 return false;
10737 }
10738
10739 final long origId = Binder.clearCallingIdentity();
10740
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010741 while (clist.size() > 0) {
10742 ConnectionRecord r = clist.get(0);
10743 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010744
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010745 if (r.binding.service.app != null) {
10746 // This could have made the service less important.
10747 updateOomAdjLocked(r.binding.service.app);
10748 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010749 }
10750
10751 Binder.restoreCallingIdentity(origId);
10752 }
10753
10754 return true;
10755 }
10756
10757 public void publishService(IBinder token, Intent intent, IBinder service) {
10758 // Refuse possible leaked file descriptors
10759 if (intent != null && intent.hasFileDescriptors() == true) {
10760 throw new IllegalArgumentException("File descriptors passed in Intent");
10761 }
10762
10763 synchronized(this) {
10764 if (!(token instanceof ServiceRecord)) {
10765 throw new IllegalArgumentException("Invalid service token");
10766 }
10767 ServiceRecord r = (ServiceRecord)token;
10768
10769 final long origId = Binder.clearCallingIdentity();
10770
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010771 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010772 + " " + intent + ": " + service);
10773 if (r != null) {
10774 Intent.FilterComparison filter
10775 = new Intent.FilterComparison(intent);
10776 IntentBindRecord b = r.bindings.get(filter);
10777 if (b != null && !b.received) {
10778 b.binder = service;
10779 b.requested = true;
10780 b.received = true;
10781 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010782 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010783 = r.connections.values().iterator();
10784 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010785 ArrayList<ConnectionRecord> clist = it.next();
10786 for (int i=0; i<clist.size(); i++) {
10787 ConnectionRecord c = clist.get(i);
10788 if (!filter.equals(c.binding.intent.intent)) {
10789 if (DEBUG_SERVICE) Slog.v(
10790 TAG, "Not publishing to: " + c);
10791 if (DEBUG_SERVICE) Slog.v(
10792 TAG, "Bound intent: " + c.binding.intent.intent);
10793 if (DEBUG_SERVICE) Slog.v(
10794 TAG, "Published intent: " + intent);
10795 continue;
10796 }
10797 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10798 try {
10799 c.conn.connected(r.name, service);
10800 } catch (Exception e) {
10801 Slog.w(TAG, "Failure sending service " + r.name +
10802 " to connection " + c.conn.asBinder() +
10803 " (in " + c.binding.client.processName + ")", e);
10804 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010805 }
10806 }
10807 }
10808 }
10809
10810 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10811
10812 Binder.restoreCallingIdentity(origId);
10813 }
10814 }
10815 }
10816
10817 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10818 // Refuse possible leaked file descriptors
10819 if (intent != null && intent.hasFileDescriptors() == true) {
10820 throw new IllegalArgumentException("File descriptors passed in Intent");
10821 }
10822
10823 synchronized(this) {
10824 if (!(token instanceof ServiceRecord)) {
10825 throw new IllegalArgumentException("Invalid service token");
10826 }
10827 ServiceRecord r = (ServiceRecord)token;
10828
10829 final long origId = Binder.clearCallingIdentity();
10830
10831 if (r != null) {
10832 Intent.FilterComparison filter
10833 = new Intent.FilterComparison(intent);
10834 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010835 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010836 + " at " + b + ": apps="
10837 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020010838
10839 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010840 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020010841 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010842 // Applications have already bound since the last
10843 // unbind, so just rebind right here.
10844 requestServiceBindingLocked(r, b, true);
10845 } else {
10846 // Note to tell the service the next time there is
10847 // a new client.
10848 b.doRebind = true;
10849 }
10850 }
10851
Per Edelberg78f9fff2010-08-30 20:01:35 +020010852 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010853
10854 Binder.restoreCallingIdentity(origId);
10855 }
10856 }
10857 }
10858
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010859 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010860 synchronized(this) {
10861 if (!(token instanceof ServiceRecord)) {
10862 throw new IllegalArgumentException("Invalid service token");
10863 }
10864 ServiceRecord r = (ServiceRecord)token;
10865 boolean inStopping = mStoppingServices.contains(token);
10866 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010867 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010868 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010869 + " with incorrect token: given " + token
10870 + ", expected " + r);
10871 return;
10872 }
10873
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010874 if (type == 1) {
10875 // This is a call from a service start... take care of
10876 // book-keeping.
10877 r.callStart = true;
10878 switch (res) {
10879 case Service.START_STICKY_COMPATIBILITY:
10880 case Service.START_STICKY: {
10881 // We are done with the associated start arguments.
10882 r.findDeliveredStart(startId, true);
10883 // Don't stop if killed.
10884 r.stopIfKilled = false;
10885 break;
10886 }
10887 case Service.START_NOT_STICKY: {
10888 // We are done with the associated start arguments.
10889 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010890 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010891 // There is no more work, and this service
10892 // doesn't want to hang around if killed.
10893 r.stopIfKilled = true;
10894 }
10895 break;
10896 }
10897 case Service.START_REDELIVER_INTENT: {
10898 // We'll keep this item until they explicitly
10899 // call stop for it, but keep track of the fact
10900 // that it was delivered.
10901 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10902 if (si != null) {
10903 si.deliveryCount = 0;
10904 si.doneExecutingCount++;
10905 // Don't stop if killed.
10906 r.stopIfKilled = true;
10907 }
10908 break;
10909 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010910 case Service.START_TASK_REMOVED_COMPLETE: {
10911 // Special processing for onTaskRemoved(). Don't
10912 // impact normal onStartCommand() processing.
10913 r.findDeliveredStart(startId, true);
10914 break;
10915 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010916 default:
10917 throw new IllegalArgumentException(
10918 "Unknown service start result: " + res);
10919 }
10920 if (res == Service.START_STICKY_COMPATIBILITY) {
10921 r.callStart = false;
10922 }
10923 }
10924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010925 final long origId = Binder.clearCallingIdentity();
10926 serviceDoneExecutingLocked(r, inStopping);
10927 Binder.restoreCallingIdentity(origId);
10928 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010929 Slog.w(TAG, "Done executing unknown service from pid "
10930 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010931 }
10932 }
10933 }
10934
10935 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010936 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10937 + ": nesting=" + r.executeNesting
10938 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010939 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010940 r.executeNesting--;
10941 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010942 if (DEBUG_SERVICE) Slog.v(TAG,
10943 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010944 r.app.executingServices.remove(r);
10945 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010946 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10947 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010948 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10949 }
10950 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010951 if (DEBUG_SERVICE) Slog.v(TAG,
10952 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010953 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010954 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010955 }
10956 updateOomAdjLocked(r.app);
10957 }
10958 }
10959
10960 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010961 String anrMessage = null;
10962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010963 synchronized(this) {
10964 if (proc.executingServices.size() == 0 || proc.thread == null) {
10965 return;
10966 }
10967 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10968 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10969 ServiceRecord timeout = null;
10970 long nextTime = 0;
10971 while (it.hasNext()) {
10972 ServiceRecord sr = it.next();
10973 if (sr.executingStart < maxTime) {
10974 timeout = sr;
10975 break;
10976 }
10977 if (sr.executingStart > nextTime) {
10978 nextTime = sr.executingStart;
10979 }
10980 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010981 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010982 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010983 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010984 } else {
10985 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10986 msg.obj = proc;
10987 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10988 }
10989 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010990
10991 if (anrMessage != null) {
10992 appNotResponding(proc, null, null, anrMessage);
10993 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010994 }
10995
10996 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010997 // BACKUP AND RESTORE
10998 // =========================================================
10999
11000 // Cause the target app to be launched if necessary and its backup agent
11001 // instantiated. The backup agent will invoke backupAgentCreated() on the
11002 // activity manager to announce its creation.
11003 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011004 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011005 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11006
11007 synchronized(this) {
11008 // !!! TODO: currently no check here that we're already bound
11009 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11010 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11011 synchronized (stats) {
11012 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11013 }
11014
Dianne Hackborne7f97212011-02-24 14:40:20 -080011015 // Backup agent is now in use, its package can't be stopped.
11016 try {
11017 AppGlobals.getPackageManager().setPackageStoppedState(
11018 app.packageName, false);
11019 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011020 } catch (IllegalArgumentException e) {
11021 Slog.w(TAG, "Failed trying to unstop package "
11022 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011023 }
11024
Christopher Tate181fafa2009-05-14 11:12:14 -070011025 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011026 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11027 ? new ComponentName(app.packageName, app.backupAgentName)
11028 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011029 // startProcessLocked() returns existing proc's record if it's already running
11030 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011031 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011032 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011033 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011034 return false;
11035 }
11036
11037 r.app = proc;
11038 mBackupTarget = r;
11039 mBackupAppName = app.packageName;
11040
Christopher Tate6fa95972009-06-05 18:43:55 -070011041 // Try not to kill the process during backup
11042 updateOomAdjLocked(proc);
11043
Christopher Tate181fafa2009-05-14 11:12:14 -070011044 // If the process is already attached, schedule the creation of the backup agent now.
11045 // If it is not yet live, this will be done when it attaches to the framework.
11046 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011047 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011048 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011049 proc.thread.scheduleCreateBackupAgent(app,
11050 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011051 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011052 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011053 }
11054 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011055 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011056 }
11057 // Invariants: at this point, the target app process exists and the application
11058 // is either already running or in the process of coming up. mBackupTarget and
11059 // mBackupAppName describe the app, so that when it binds back to the AM we
11060 // know that it's scheduled for a backup-agent operation.
11061 }
11062
11063 return true;
11064 }
11065
11066 // A backup agent has just come up
11067 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011068 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011069 + " = " + agent);
11070
11071 synchronized(this) {
11072 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011073 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011074 return;
11075 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011076 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011077
Dianne Hackborn06740692010-09-22 22:46:21 -070011078 long oldIdent = Binder.clearCallingIdentity();
11079 try {
11080 IBackupManager bm = IBackupManager.Stub.asInterface(
11081 ServiceManager.getService(Context.BACKUP_SERVICE));
11082 bm.agentConnected(agentPackageName, agent);
11083 } catch (RemoteException e) {
11084 // can't happen; the backup manager service is local
11085 } catch (Exception e) {
11086 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11087 e.printStackTrace();
11088 } finally {
11089 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011090 }
11091 }
11092
11093 // done with this agent
11094 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011095 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011096 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011097 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011098 return;
11099 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011100
11101 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011102 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011103 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011104 return;
11105 }
11106
Christopher Tate181fafa2009-05-14 11:12:14 -070011107 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011108 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011109 return;
11110 }
11111
Christopher Tate6fa95972009-06-05 18:43:55 -070011112 ProcessRecord proc = mBackupTarget.app;
11113 mBackupTarget = null;
11114 mBackupAppName = null;
11115
11116 // Not backing this app up any more; reset its OOM adjustment
11117 updateOomAdjLocked(proc);
11118
Christopher Tatec7b31e32009-06-10 15:49:30 -070011119 // If the app crashed during backup, 'thread' will be null here
11120 if (proc.thread != null) {
11121 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011122 proc.thread.scheduleDestroyBackupAgent(appInfo,
11123 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011124 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011125 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011126 e.printStackTrace();
11127 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011128 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011129 }
11130 }
11131 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011132 // BROADCASTS
11133 // =========================================================
11134
Josh Bartel7f208742010-02-25 11:01:44 -060011135 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011136 List cur) {
11137 final ContentResolver resolver = mContext.getContentResolver();
11138 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11139 if (list == null) {
11140 return cur;
11141 }
11142 int N = list.size();
11143 for (int i=0; i<N; i++) {
11144 Intent intent = list.get(i);
11145 if (filter.match(resolver, intent, true, TAG) >= 0) {
11146 if (cur == null) {
11147 cur = new ArrayList<Intent>();
11148 }
11149 cur.add(intent);
11150 }
11151 }
11152 return cur;
11153 }
11154
11155 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011156 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011157 + mBroadcastsScheduled);
11158
11159 if (mBroadcastsScheduled) {
11160 return;
11161 }
11162 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11163 mBroadcastsScheduled = true;
11164 }
11165
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011166 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011167 IIntentReceiver receiver, IntentFilter filter, String permission) {
11168 synchronized(this) {
11169 ProcessRecord callerApp = null;
11170 if (caller != null) {
11171 callerApp = getRecordForAppLocked(caller);
11172 if (callerApp == null) {
11173 throw new SecurityException(
11174 "Unable to find app for caller " + caller
11175 + " (pid=" + Binder.getCallingPid()
11176 + ") when registering receiver " + receiver);
11177 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011178 if (callerApp.info.uid != Process.SYSTEM_UID &&
11179 !callerApp.pkgList.contains(callerPackage)) {
11180 throw new SecurityException("Given caller package " + callerPackage
11181 + " is not running in process " + callerApp);
11182 }
11183 } else {
11184 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011185 }
11186
11187 List allSticky = null;
11188
11189 // Look for any matching sticky broadcasts...
11190 Iterator actions = filter.actionsIterator();
11191 if (actions != null) {
11192 while (actions.hasNext()) {
11193 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011194 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011195 }
11196 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011197 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011198 }
11199
11200 // The first sticky in the list is returned directly back to
11201 // the client.
11202 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11203
Joe Onorato8a9b2202010-02-26 18:56:32 -080011204 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011205 + ": " + sticky);
11206
11207 if (receiver == null) {
11208 return sticky;
11209 }
11210
11211 ReceiverList rl
11212 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11213 if (rl == null) {
11214 rl = new ReceiverList(this, callerApp,
11215 Binder.getCallingPid(),
11216 Binder.getCallingUid(), receiver);
11217 if (rl.app != null) {
11218 rl.app.receivers.add(rl);
11219 } else {
11220 try {
11221 receiver.asBinder().linkToDeath(rl, 0);
11222 } catch (RemoteException e) {
11223 return sticky;
11224 }
11225 rl.linkedToDeath = true;
11226 }
11227 mRegisteredReceivers.put(receiver.asBinder(), rl);
11228 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011229 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011230 rl.add(bf);
11231 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011232 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011233 }
11234 mReceiverResolver.addFilter(bf);
11235
11236 // Enqueue broadcasts for all existing stickies that match
11237 // this filter.
11238 if (allSticky != null) {
11239 ArrayList receivers = new ArrayList();
11240 receivers.add(bf);
11241
11242 int N = allSticky.size();
11243 for (int i=0; i<N; i++) {
11244 Intent intent = (Intent)allSticky.get(i);
11245 BroadcastRecord r = new BroadcastRecord(intent, null,
11246 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011247 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011248 if (mParallelBroadcasts.size() == 0) {
11249 scheduleBroadcastsLocked();
11250 }
11251 mParallelBroadcasts.add(r);
11252 }
11253 }
11254
11255 return sticky;
11256 }
11257 }
11258
11259 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011260 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011261
11262 boolean doNext = false;
11263
11264 synchronized(this) {
11265 ReceiverList rl
11266 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11267 if (rl != null) {
11268 if (rl.curBroadcast != null) {
11269 BroadcastRecord r = rl.curBroadcast;
11270 doNext = finishReceiverLocked(
11271 receiver.asBinder(), r.resultCode, r.resultData,
11272 r.resultExtras, r.resultAbort, true);
11273 }
11274
11275 if (rl.app != null) {
11276 rl.app.receivers.remove(rl);
11277 }
11278 removeReceiverLocked(rl);
11279 if (rl.linkedToDeath) {
11280 rl.linkedToDeath = false;
11281 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11282 }
11283 }
11284 }
11285
11286 if (!doNext) {
11287 return;
11288 }
11289
11290 final long origId = Binder.clearCallingIdentity();
11291 processNextBroadcast(false);
11292 trimApplications();
11293 Binder.restoreCallingIdentity(origId);
11294 }
11295
11296 void removeReceiverLocked(ReceiverList rl) {
11297 mRegisteredReceivers.remove(rl.receiver.asBinder());
11298 int N = rl.size();
11299 for (int i=0; i<N; i++) {
11300 mReceiverResolver.removeFilter(rl.get(i));
11301 }
11302 }
11303
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011304 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11305 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11306 ProcessRecord r = mLruProcesses.get(i);
11307 if (r.thread != null) {
11308 try {
11309 r.thread.dispatchPackageBroadcast(cmd, packages);
11310 } catch (RemoteException ex) {
11311 }
11312 }
11313 }
11314 }
11315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011316 private final int broadcastIntentLocked(ProcessRecord callerApp,
11317 String callerPackage, Intent intent, String resolvedType,
11318 IIntentReceiver resultTo, int resultCode, String resultData,
11319 Bundle map, String requiredPermission,
11320 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11321 intent = new Intent(intent);
11322
Dianne Hackborne7f97212011-02-24 14:40:20 -080011323 // By default broadcasts do not go to stopped apps.
11324 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11325
Joe Onorato8a9b2202010-02-26 18:56:32 -080011326 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011327 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11328 + " ordered=" + ordered);
11329 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011330 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011331 }
11332
11333 // Handle special intents: if this broadcast is from the package
11334 // manager about a package being removed, we need to remove all of
11335 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011336 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011337 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011338 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11339 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011340 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011341 || uidRemoved) {
11342 if (checkComponentPermission(
11343 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011344 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011345 == PackageManager.PERMISSION_GRANTED) {
11346 if (uidRemoved) {
11347 final Bundle intentExtras = intent.getExtras();
11348 final int uid = intentExtras != null
11349 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11350 if (uid >= 0) {
11351 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11352 synchronized (bs) {
11353 bs.removeUidStatsLocked(uid);
11354 }
11355 }
11356 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011357 // If resources are unvailble just force stop all
11358 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011359 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011360 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11361 if (list != null && (list.length > 0)) {
11362 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011363 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011364 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011365 sendPackageBroadcastLocked(
11366 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011367 }
11368 } else {
11369 Uri data = intent.getData();
11370 String ssp;
11371 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11372 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11373 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011374 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011375 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011376 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011377 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11378 new String[] {ssp});
11379 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011380 }
11381 }
11382 }
11383 } else {
11384 String msg = "Permission Denial: " + intent.getAction()
11385 + " broadcast from " + callerPackage + " (pid=" + callingPid
11386 + ", uid=" + callingUid + ")"
11387 + " requires "
11388 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011389 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011390 throw new SecurityException(msg);
11391 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011392
11393 // Special case for adding a package: by default turn on compatibility
11394 // mode.
11395 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011396 Uri data = intent.getData();
11397 String ssp;
11398 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11399 mCompatModePackages.handlePackageAddedLocked(ssp,
11400 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011401 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011402 }
11403
11404 /*
11405 * If this is the time zone changed action, queue up a message that will reset the timezone
11406 * of all currently running processes. This message will get queued up before the broadcast
11407 * happens.
11408 */
11409 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11410 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11411 }
11412
Robert Greenwalt03595d02010-11-02 14:08:23 -070011413 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11414 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11415 }
11416
Robert Greenwalt434203a2010-10-11 16:00:27 -070011417 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11418 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11419 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11420 }
11421
Dianne Hackborn854060af2009-07-09 18:14:31 -070011422 /*
11423 * Prevent non-system code (defined here to be non-persistent
11424 * processes) from sending protected broadcasts.
11425 */
11426 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11427 || callingUid == Process.SHELL_UID || callingUid == 0) {
11428 // Always okay.
11429 } else if (callerApp == null || !callerApp.persistent) {
11430 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011431 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011432 intent.getAction())) {
11433 String msg = "Permission Denial: not allowed to send broadcast "
11434 + intent.getAction() + " from pid="
11435 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011436 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011437 throw new SecurityException(msg);
11438 }
11439 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011440 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011441 return BROADCAST_SUCCESS;
11442 }
11443 }
11444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011445 // Add to the sticky list if requested.
11446 if (sticky) {
11447 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11448 callingPid, callingUid)
11449 != PackageManager.PERMISSION_GRANTED) {
11450 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11451 + callingPid + ", uid=" + callingUid
11452 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011453 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011454 throw new SecurityException(msg);
11455 }
11456 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011457 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011458 + " and enforce permission " + requiredPermission);
11459 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11460 }
11461 if (intent.getComponent() != null) {
11462 throw new SecurityException(
11463 "Sticky broadcasts can't target a specific component");
11464 }
11465 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11466 if (list == null) {
11467 list = new ArrayList<Intent>();
11468 mStickyBroadcasts.put(intent.getAction(), list);
11469 }
11470 int N = list.size();
11471 int i;
11472 for (i=0; i<N; i++) {
11473 if (intent.filterEquals(list.get(i))) {
11474 // This sticky already exists, replace it.
11475 list.set(i, new Intent(intent));
11476 break;
11477 }
11478 }
11479 if (i >= N) {
11480 list.add(new Intent(intent));
11481 }
11482 }
11483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011484 // Figure out who all will receive this broadcast.
11485 List receivers = null;
11486 List<BroadcastFilter> registeredReceivers = null;
11487 try {
11488 if (intent.getComponent() != null) {
11489 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011490 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011491 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011492 if (ai != null) {
11493 receivers = new ArrayList();
11494 ResolveInfo ri = new ResolveInfo();
11495 ri.activityInfo = ai;
11496 receivers.add(ri);
11497 }
11498 } else {
11499 // Need to resolve the intent to interested receivers...
11500 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11501 == 0) {
11502 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011503 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011504 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011505 }
Mihai Preda074edef2009-05-18 17:13:31 +020011506 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011507 }
11508 } catch (RemoteException ex) {
11509 // pm is in same process, this will never happen.
11510 }
11511
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011512 final boolean replacePending =
11513 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11514
Joe Onorato8a9b2202010-02-26 18:56:32 -080011515 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011516 + " replacePending=" + replacePending);
11517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011518 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11519 if (!ordered && NR > 0) {
11520 // If we are not serializing this broadcast, then send the
11521 // registered receivers separately so they don't wait for the
11522 // components to be launched.
11523 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11524 callerPackage, callingPid, callingUid, requiredPermission,
11525 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011526 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011527 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011528 TAG, "Enqueueing parallel broadcast " + r
11529 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011530 boolean replaced = false;
11531 if (replacePending) {
11532 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11533 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011534 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011535 "***** DROPPING PARALLEL: " + intent);
11536 mParallelBroadcasts.set(i, r);
11537 replaced = true;
11538 break;
11539 }
11540 }
11541 }
11542 if (!replaced) {
11543 mParallelBroadcasts.add(r);
11544 scheduleBroadcastsLocked();
11545 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011546 registeredReceivers = null;
11547 NR = 0;
11548 }
11549
11550 // Merge into one list.
11551 int ir = 0;
11552 if (receivers != null) {
11553 // A special case for PACKAGE_ADDED: do not allow the package
11554 // being added to see this broadcast. This prevents them from
11555 // using this as a back door to get run as soon as they are
11556 // installed. Maybe in the future we want to have a special install
11557 // broadcast or such for apps, but we'd like to deliberately make
11558 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011559 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011560 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11561 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11562 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011563 Uri data = intent.getData();
11564 if (data != null) {
11565 String pkgName = data.getSchemeSpecificPart();
11566 if (pkgName != null) {
11567 skipPackages = new String[] { pkgName };
11568 }
11569 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011570 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011571 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011572 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011573 if (skipPackages != null && (skipPackages.length > 0)) {
11574 for (String skipPackage : skipPackages) {
11575 if (skipPackage != null) {
11576 int NT = receivers.size();
11577 for (int it=0; it<NT; it++) {
11578 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11579 if (curt.activityInfo.packageName.equals(skipPackage)) {
11580 receivers.remove(it);
11581 it--;
11582 NT--;
11583 }
11584 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011585 }
11586 }
11587 }
11588
11589 int NT = receivers != null ? receivers.size() : 0;
11590 int it = 0;
11591 ResolveInfo curt = null;
11592 BroadcastFilter curr = null;
11593 while (it < NT && ir < NR) {
11594 if (curt == null) {
11595 curt = (ResolveInfo)receivers.get(it);
11596 }
11597 if (curr == null) {
11598 curr = registeredReceivers.get(ir);
11599 }
11600 if (curr.getPriority() >= curt.priority) {
11601 // Insert this broadcast record into the final list.
11602 receivers.add(it, curr);
11603 ir++;
11604 curr = null;
11605 it++;
11606 NT++;
11607 } else {
11608 // Skip to the next ResolveInfo in the final list.
11609 it++;
11610 curt = null;
11611 }
11612 }
11613 }
11614 while (ir < NR) {
11615 if (receivers == null) {
11616 receivers = new ArrayList();
11617 }
11618 receivers.add(registeredReceivers.get(ir));
11619 ir++;
11620 }
11621
11622 if ((receivers != null && receivers.size() > 0)
11623 || resultTo != null) {
11624 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11625 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011626 receivers, resultTo, resultCode, resultData, map, ordered,
11627 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011628 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011629 TAG, "Enqueueing ordered broadcast " + r
11630 + ": prev had " + mOrderedBroadcasts.size());
11631 if (DEBUG_BROADCAST) {
11632 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011633 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011634 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011635 boolean replaced = false;
11636 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011637 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011638 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011639 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011640 "***** DROPPING ORDERED: " + intent);
11641 mOrderedBroadcasts.set(i, r);
11642 replaced = true;
11643 break;
11644 }
11645 }
11646 }
11647 if (!replaced) {
11648 mOrderedBroadcasts.add(r);
11649 scheduleBroadcastsLocked();
11650 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011651 }
11652
11653 return BROADCAST_SUCCESS;
11654 }
11655
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011656 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011657 // Refuse possible leaked file descriptors
11658 if (intent != null && intent.hasFileDescriptors() == true) {
11659 throw new IllegalArgumentException("File descriptors passed in Intent");
11660 }
11661
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011662 int flags = intent.getFlags();
11663
11664 if (!mProcessesReady) {
11665 // if the caller really truly claims to know what they're doing, go
11666 // ahead and allow the broadcast without launching any receivers
11667 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11668 intent = new Intent(intent);
11669 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11670 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11671 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11672 + " before boot completion");
11673 throw new IllegalStateException("Cannot broadcast before boot completed");
11674 }
11675 }
11676
11677 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11678 throw new IllegalArgumentException(
11679 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11680 }
11681
11682 return intent;
11683 }
11684
11685 public final int broadcastIntent(IApplicationThread caller,
11686 Intent intent, String resolvedType, IIntentReceiver resultTo,
11687 int resultCode, String resultData, Bundle map,
11688 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011689 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011690 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011692 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11693 final int callingPid = Binder.getCallingPid();
11694 final int callingUid = Binder.getCallingUid();
11695 final long origId = Binder.clearCallingIdentity();
11696 int res = broadcastIntentLocked(callerApp,
11697 callerApp != null ? callerApp.info.packageName : null,
11698 intent, resolvedType, resultTo,
11699 resultCode, resultData, map, requiredPermission, serialized,
11700 sticky, callingPid, callingUid);
11701 Binder.restoreCallingIdentity(origId);
11702 return res;
11703 }
11704 }
11705
11706 int broadcastIntentInPackage(String packageName, int uid,
11707 Intent intent, String resolvedType, IIntentReceiver resultTo,
11708 int resultCode, String resultData, Bundle map,
11709 String requiredPermission, boolean serialized, boolean sticky) {
11710 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011711 intent = verifyBroadcastLocked(intent);
11712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011713 final long origId = Binder.clearCallingIdentity();
11714 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11715 resultTo, resultCode, resultData, map, requiredPermission,
11716 serialized, sticky, -1, uid);
11717 Binder.restoreCallingIdentity(origId);
11718 return res;
11719 }
11720 }
11721
11722 public final void unbroadcastIntent(IApplicationThread caller,
11723 Intent intent) {
11724 // Refuse possible leaked file descriptors
11725 if (intent != null && intent.hasFileDescriptors() == true) {
11726 throw new IllegalArgumentException("File descriptors passed in Intent");
11727 }
11728
11729 synchronized(this) {
11730 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11731 != PackageManager.PERMISSION_GRANTED) {
11732 String msg = "Permission Denial: unbroadcastIntent() from pid="
11733 + Binder.getCallingPid()
11734 + ", uid=" + Binder.getCallingUid()
11735 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011736 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011737 throw new SecurityException(msg);
11738 }
11739 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11740 if (list != null) {
11741 int N = list.size();
11742 int i;
11743 for (i=0; i<N; i++) {
11744 if (intent.filterEquals(list.get(i))) {
11745 list.remove(i);
11746 break;
11747 }
11748 }
11749 }
11750 }
11751 }
11752
11753 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11754 String resultData, Bundle resultExtras, boolean resultAbort,
11755 boolean explicit) {
11756 if (mOrderedBroadcasts.size() == 0) {
11757 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011758 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011759 }
11760 return false;
11761 }
11762 BroadcastRecord r = mOrderedBroadcasts.get(0);
11763 if (r.receiver == null) {
11764 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011765 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011766 }
11767 return false;
11768 }
11769 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011770 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011771 return false;
11772 }
11773 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011774 r.state = BroadcastRecord.IDLE;
11775 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011776 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011777 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011778 }
11779 }
11780 r.receiver = null;
11781 r.intent.setComponent(null);
11782 if (r.curApp != null) {
11783 r.curApp.curReceiver = null;
11784 }
11785 if (r.curFilter != null) {
11786 r.curFilter.receiverList.curBroadcast = null;
11787 }
11788 r.curFilter = null;
11789 r.curApp = null;
11790 r.curComponent = null;
11791 r.curReceiver = null;
11792 mPendingBroadcast = null;
11793
11794 r.resultCode = resultCode;
11795 r.resultData = resultData;
11796 r.resultExtras = resultExtras;
11797 r.resultAbort = resultAbort;
11798
11799 // We will process the next receiver right now if this is finishing
11800 // an app receiver (which is always asynchronous) or after we have
11801 // come back from calling a receiver.
11802 return state == BroadcastRecord.APP_RECEIVE
11803 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11804 }
11805
11806 public void finishReceiver(IBinder who, int resultCode, String resultData,
11807 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011808 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011809
11810 // Refuse possible leaked file descriptors
11811 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11812 throw new IllegalArgumentException("File descriptors passed in Bundle");
11813 }
11814
11815 boolean doNext;
11816
11817 final long origId = Binder.clearCallingIdentity();
11818
11819 synchronized(this) {
11820 doNext = finishReceiverLocked(
11821 who, resultCode, resultData, resultExtras, resultAbort, true);
11822 }
11823
11824 if (doNext) {
11825 processNextBroadcast(false);
11826 }
11827 trimApplications();
11828
11829 Binder.restoreCallingIdentity(origId);
11830 }
11831
Jeff Brown4d94a762010-09-23 11:33:28 -070011832 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011833 if (r.nextReceiver > 0) {
11834 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11835 if (curReceiver instanceof BroadcastFilter) {
11836 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011837 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011838 System.identityHashCode(r),
11839 r.intent.getAction(),
11840 r.nextReceiver - 1,
11841 System.identityHashCode(bf));
11842 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011843 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011844 System.identityHashCode(r),
11845 r.intent.getAction(),
11846 r.nextReceiver - 1,
11847 ((ResolveInfo)curReceiver).toString());
11848 }
11849 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011850 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011851 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011852 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011853 System.identityHashCode(r),
11854 r.intent.getAction(),
11855 r.nextReceiver,
11856 "NONE");
11857 }
11858 }
11859
Jeff Brown4d94a762010-09-23 11:33:28 -070011860 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11861 if (! mPendingBroadcastTimeoutMessage) {
11862 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11863 mHandler.sendMessageAtTime(msg, timeoutTime);
11864 mPendingBroadcastTimeoutMessage = true;
11865 }
11866 }
11867
11868 private final void cancelBroadcastTimeoutLocked() {
11869 if (mPendingBroadcastTimeoutMessage) {
11870 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11871 mPendingBroadcastTimeoutMessage = false;
11872 }
11873 }
11874
11875 private final void broadcastTimeoutLocked(boolean fromMsg) {
11876 if (fromMsg) {
11877 mPendingBroadcastTimeoutMessage = false;
11878 }
11879
11880 if (mOrderedBroadcasts.size() == 0) {
11881 return;
11882 }
11883
11884 long now = SystemClock.uptimeMillis();
11885 BroadcastRecord r = mOrderedBroadcasts.get(0);
11886 if (fromMsg) {
11887 if (mDidDexOpt) {
11888 // Delay timeouts until dexopt finishes.
11889 mDidDexOpt = false;
11890 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11891 setBroadcastTimeoutLocked(timeoutTime);
11892 return;
11893 }
11894 if (! mProcessesReady) {
11895 // Only process broadcast timeouts if the system is ready. That way
11896 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11897 // to do heavy lifting for system up.
11898 return;
11899 }
11900
11901 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11902 if (timeoutTime > now) {
11903 // We can observe premature timeouts because we do not cancel and reset the
11904 // broadcast timeout message after each receiver finishes. Instead, we set up
11905 // an initial timeout then kick it down the road a little further as needed
11906 // when it expires.
11907 if (DEBUG_BROADCAST) Slog.v(TAG,
11908 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11909 + timeoutTime);
11910 setBroadcastTimeoutLocked(timeoutTime);
11911 return;
11912 }
11913 }
11914
11915 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11916 + ", started " + (now - r.receiverTime) + "ms ago");
11917 r.receiverTime = now;
11918 r.anrCount++;
11919
11920 // Current receiver has passed its expiration date.
11921 if (r.nextReceiver <= 0) {
11922 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11923 return;
11924 }
11925
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011926 ProcessRecord app = null;
11927 String anrMessage = null;
11928
Jeff Brown4d94a762010-09-23 11:33:28 -070011929 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11930 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11931 logBroadcastReceiverDiscardLocked(r);
11932 if (curReceiver instanceof BroadcastFilter) {
11933 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11934 if (bf.receiverList.pid != 0
11935 && bf.receiverList.pid != MY_PID) {
11936 synchronized (this.mPidsSelfLocked) {
11937 app = this.mPidsSelfLocked.get(
11938 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011939 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011940 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011941 } else {
11942 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011943 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011944
Jeff Brown4d94a762010-09-23 11:33:28 -070011945 if (app != null) {
11946 anrMessage = "Broadcast of " + r.intent.toString();
11947 }
11948
11949 if (mPendingBroadcast == r) {
11950 mPendingBroadcast = null;
11951 }
11952
11953 // Move on to the next receiver.
11954 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11955 r.resultExtras, r.resultAbort, true);
11956 scheduleBroadcastsLocked();
11957
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011958 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011959 // Post the ANR to the handler since we do not want to process ANRs while
11960 // potentially holding our lock.
11961 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011963 }
11964
11965 private final void processCurBroadcastLocked(BroadcastRecord r,
11966 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011967 if (DEBUG_BROADCAST) Slog.v(TAG,
11968 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011969 if (app.thread == null) {
11970 throw new RemoteException();
11971 }
11972 r.receiver = app.thread.asBinder();
11973 r.curApp = app;
11974 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011975 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011976
11977 // Tell the application to launch this receiver.
11978 r.intent.setComponent(r.curComponent);
11979
11980 boolean started = false;
11981 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011982 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011983 "Delivering to component " + r.curComponent
11984 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011985 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011986 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011987 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011988 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011989 if (DEBUG_BROADCAST) Slog.v(TAG,
11990 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011991 started = true;
11992 } finally {
11993 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011994 if (DEBUG_BROADCAST) Slog.v(TAG,
11995 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011996 r.receiver = null;
11997 r.curApp = null;
11998 app.curReceiver = null;
11999 }
12000 }
12001
12002 }
12003
Jeff Brown4d94a762010-09-23 11:33:28 -070012004 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012005 Intent intent, int resultCode, String data, Bundle extras,
12006 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012007 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012008 if (app != null && app.thread != null) {
12009 // If we have an app thread, do the call through that so it is
12010 // correctly ordered with other one-way calls.
12011 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012012 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012013 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012014 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012015 }
12016 }
12017
Jeff Brown4d94a762010-09-23 11:33:28 -070012018 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012019 BroadcastFilter filter, boolean ordered) {
12020 boolean skip = false;
12021 if (filter.requiredPermission != null) {
12022 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012023 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012024 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012025 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012026 + r.intent.toString()
12027 + " from " + r.callerPackage + " (pid="
12028 + r.callingPid + ", uid=" + r.callingUid + ")"
12029 + " requires " + filter.requiredPermission
12030 + " due to registered receiver " + filter);
12031 skip = true;
12032 }
12033 }
12034 if (r.requiredPermission != null) {
12035 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012036 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012037 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012038 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012039 + r.intent.toString()
12040 + " to " + filter.receiverList.app
12041 + " (pid=" + filter.receiverList.pid
12042 + ", uid=" + filter.receiverList.uid + ")"
12043 + " requires " + r.requiredPermission
12044 + " due to sender " + r.callerPackage
12045 + " (uid " + r.callingUid + ")");
12046 skip = true;
12047 }
12048 }
12049
12050 if (!skip) {
12051 // If this is not being sent as an ordered broadcast, then we
12052 // don't want to touch the fields that keep track of the current
12053 // state of ordered broadcasts.
12054 if (ordered) {
12055 r.receiver = filter.receiverList.receiver.asBinder();
12056 r.curFilter = filter;
12057 filter.receiverList.curBroadcast = r;
12058 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012059 if (filter.receiverList.app != null) {
12060 // Bump hosting application to no longer be in background
12061 // scheduling class. Note that we can't do that if there
12062 // isn't an app... but we can only be in that case for
12063 // things that directly call the IActivityManager API, which
12064 // are already core system stuff so don't matter for this.
12065 r.curApp = filter.receiverList.app;
12066 filter.receiverList.app.curReceiver = r;
12067 updateOomAdjLocked();
12068 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012069 }
12070 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012071 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012072 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012073 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012074 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012075 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012076 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012077 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012078 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012079 if (ordered) {
12080 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12081 }
12082 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012083 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012084 if (ordered) {
12085 r.receiver = null;
12086 r.curFilter = null;
12087 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012088 if (filter.receiverList.app != null) {
12089 filter.receiverList.app.curReceiver = null;
12090 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012091 }
12092 }
12093 }
12094 }
12095
Dianne Hackborn12527f92009-11-11 17:39:50 -080012096 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12097 if (r.callingUid < 0) {
12098 // This was from a registerReceiver() call; ignore it.
12099 return;
12100 }
12101 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12102 MAX_BROADCAST_HISTORY-1);
12103 r.finishTime = SystemClock.uptimeMillis();
12104 mBroadcastHistory[0] = r;
12105 }
12106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012107 private final void processNextBroadcast(boolean fromMsg) {
12108 synchronized(this) {
12109 BroadcastRecord r;
12110
Joe Onorato8a9b2202010-02-26 18:56:32 -080012111 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012112 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012113 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012114
12115 updateCpuStats();
12116
12117 if (fromMsg) {
12118 mBroadcastsScheduled = false;
12119 }
12120
12121 // First, deliver any non-serialized broadcasts right away.
12122 while (mParallelBroadcasts.size() > 0) {
12123 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012124 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012125 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012126 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012127 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012128 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012129 for (int i=0; i<N; i++) {
12130 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012131 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012132 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012133 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012134 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012135 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012136 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012137 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012138 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012139 }
12140
12141 // Now take care of the next serialized one...
12142
12143 // If we are waiting for a process to come up to handle the next
12144 // broadcast, then do nothing at this point. Just in case, we
12145 // check that the process we're waiting for still exists.
12146 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012147 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012148 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012149 + mPendingBroadcast.curApp);
12150 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012151
12152 boolean isDead;
12153 synchronized (mPidsSelfLocked) {
12154 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12155 }
12156 if (!isDead) {
12157 // It's still alive, so keep waiting
12158 return;
12159 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012160 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012161 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012162 mPendingBroadcast.state = BroadcastRecord.IDLE;
12163 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012164 mPendingBroadcast = null;
12165 }
12166 }
12167
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012168 boolean looped = false;
12169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012170 do {
12171 if (mOrderedBroadcasts.size() == 0) {
12172 // No more broadcasts pending, so all done!
12173 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012174 if (looped) {
12175 // If we had finished the last ordered broadcast, then
12176 // make sure all processes have correct oom and sched
12177 // adjustments.
12178 updateOomAdjLocked();
12179 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012180 return;
12181 }
12182 r = mOrderedBroadcasts.get(0);
12183 boolean forceReceive = false;
12184
12185 // Ensure that even if something goes awry with the timeout
12186 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012187 // and continue to make progress.
12188 //
12189 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012190 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012191 // one time heavy lifting after system upgrades and can take
12192 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012193 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012194 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012195 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196 if ((numReceivers > 0) &&
12197 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012198 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012199 + " now=" + now
12200 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012201 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012202 + " intent=" + r.intent
12203 + " numReceivers=" + numReceivers
12204 + " nextReceiver=" + r.nextReceiver
12205 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012206 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012207 forceReceive = true;
12208 r.state = BroadcastRecord.IDLE;
12209 }
12210 }
12211
12212 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012213 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012214 "processNextBroadcast() called when not idle (state="
12215 + r.state + ")");
12216 return;
12217 }
12218
12219 if (r.receivers == null || r.nextReceiver >= numReceivers
12220 || r.resultAbort || forceReceive) {
12221 // No more receivers for this broadcast! Send the final
12222 // result if requested...
12223 if (r.resultTo != null) {
12224 try {
12225 if (DEBUG_BROADCAST) {
12226 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012227 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012228 + " seq=" + seq + " app=" + r.callerApp);
12229 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012230 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012231 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012232 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012233 // Set this to null so that the reference
12234 // (local and remote) isnt kept in the mBroadcastHistory.
12235 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012236 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012237 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012238 }
12239 }
12240
Joe Onorato8a9b2202010-02-26 18:56:32 -080012241 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012242 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012243
Joe Onorato8a9b2202010-02-26 18:56:32 -080012244 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012245 + r);
12246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012247 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012248 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012249 mOrderedBroadcasts.remove(0);
12250 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012251 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012252 continue;
12253 }
12254 } while (r == null);
12255
12256 // Get the next receiver...
12257 int recIdx = r.nextReceiver++;
12258
12259 // Keep track of when this receiver started, and make sure there
12260 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012261 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012262 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012263 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012264 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012265 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012266 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012267 }
12268 if (! mPendingBroadcastTimeoutMessage) {
12269 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012270 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012271 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12272 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012273 }
12274
12275 Object nextReceiver = r.receivers.get(recIdx);
12276 if (nextReceiver instanceof BroadcastFilter) {
12277 // Simple case: this is a registered receiver who gets
12278 // a direct call.
12279 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012280 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012281 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012282 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012283 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012284 if (r.receiver == null || !r.ordered) {
12285 // The receiver has already finished, so schedule to
12286 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012287 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12288 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012289 r.state = BroadcastRecord.IDLE;
12290 scheduleBroadcastsLocked();
12291 }
12292 return;
12293 }
12294
12295 // Hard case: need to instantiate the receiver, possibly
12296 // starting its application process to host it.
12297
12298 ResolveInfo info =
12299 (ResolveInfo)nextReceiver;
12300
12301 boolean skip = false;
12302 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012303 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12304 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012305 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012306 if (!info.activityInfo.exported) {
12307 Slog.w(TAG, "Permission Denial: broadcasting "
12308 + r.intent.toString()
12309 + " from " + r.callerPackage + " (pid=" + r.callingPid
12310 + ", uid=" + r.callingUid + ")"
12311 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12312 + " due to receiver " + info.activityInfo.packageName
12313 + "/" + info.activityInfo.name);
12314 } else {
12315 Slog.w(TAG, "Permission Denial: broadcasting "
12316 + r.intent.toString()
12317 + " from " + r.callerPackage + " (pid=" + r.callingPid
12318 + ", uid=" + r.callingUid + ")"
12319 + " requires " + info.activityInfo.permission
12320 + " due to receiver " + info.activityInfo.packageName
12321 + "/" + info.activityInfo.name);
12322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012323 skip = true;
12324 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012325 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012326 r.requiredPermission != null) {
12327 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012328 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012329 checkPermission(r.requiredPermission,
12330 info.activityInfo.applicationInfo.packageName);
12331 } catch (RemoteException e) {
12332 perm = PackageManager.PERMISSION_DENIED;
12333 }
12334 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012335 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012336 + r.intent + " to "
12337 + info.activityInfo.applicationInfo.packageName
12338 + " requires " + r.requiredPermission
12339 + " due to sender " + r.callerPackage
12340 + " (uid " + r.callingUid + ")");
12341 skip = true;
12342 }
12343 }
12344 if (r.curApp != null && r.curApp.crashing) {
12345 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012346 if (DEBUG_BROADCAST) Slog.v(TAG,
12347 "Skipping deliver ordered " + r + " to " + r.curApp
12348 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012349 skip = true;
12350 }
12351
12352 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012353 if (DEBUG_BROADCAST) Slog.v(TAG,
12354 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012355 r.receiver = null;
12356 r.curFilter = null;
12357 r.state = BroadcastRecord.IDLE;
12358 scheduleBroadcastsLocked();
12359 return;
12360 }
12361
12362 r.state = BroadcastRecord.APP_RECEIVE;
12363 String targetProcess = info.activityInfo.processName;
12364 r.curComponent = new ComponentName(
12365 info.activityInfo.applicationInfo.packageName,
12366 info.activityInfo.name);
12367 r.curReceiver = info.activityInfo;
12368
Dianne Hackborne7f97212011-02-24 14:40:20 -080012369 // Broadcast is being executed, its package can't be stopped.
12370 try {
12371 AppGlobals.getPackageManager().setPackageStoppedState(
12372 r.curComponent.getPackageName(), false);
12373 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012374 } catch (IllegalArgumentException e) {
12375 Slog.w(TAG, "Failed trying to unstop package "
12376 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012377 }
12378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012379 // Is this receiver's application already running?
12380 ProcessRecord app = getProcessRecordLocked(targetProcess,
12381 info.activityInfo.applicationInfo.uid);
12382 if (app != null && app.thread != null) {
12383 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012384 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012385 processCurBroadcastLocked(r, app);
12386 return;
12387 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012388 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012389 + r.curComponent, e);
12390 }
12391
12392 // If a dead object exception was thrown -- fall through to
12393 // restart the application.
12394 }
12395
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012396 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012397 if (DEBUG_BROADCAST) Slog.v(TAG,
12398 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012399 if ((r.curApp=startProcessLocked(targetProcess,
12400 info.activityInfo.applicationInfo, true,
12401 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012402 "broadcast", r.curComponent,
12403 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12404 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012405 // Ah, this recipient is unavailable. Finish it if necessary,
12406 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012407 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012408 + info.activityInfo.applicationInfo.packageName + "/"
12409 + info.activityInfo.applicationInfo.uid + " for broadcast "
12410 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012411 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012412 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12413 r.resultExtras, r.resultAbort, true);
12414 scheduleBroadcastsLocked();
12415 r.state = BroadcastRecord.IDLE;
12416 return;
12417 }
12418
12419 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012420 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012421 }
12422 }
12423
12424 // =========================================================
12425 // INSTRUMENTATION
12426 // =========================================================
12427
12428 public boolean startInstrumentation(ComponentName className,
12429 String profileFile, int flags, Bundle arguments,
12430 IInstrumentationWatcher watcher) {
12431 // Refuse possible leaked file descriptors
12432 if (arguments != null && arguments.hasFileDescriptors()) {
12433 throw new IllegalArgumentException("File descriptors passed in Bundle");
12434 }
12435
12436 synchronized(this) {
12437 InstrumentationInfo ii = null;
12438 ApplicationInfo ai = null;
12439 try {
12440 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012441 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012442 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012443 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012444 } catch (PackageManager.NameNotFoundException e) {
12445 }
12446 if (ii == null) {
12447 reportStartInstrumentationFailure(watcher, className,
12448 "Unable to find instrumentation info for: " + className);
12449 return false;
12450 }
12451 if (ai == null) {
12452 reportStartInstrumentationFailure(watcher, className,
12453 "Unable to find instrumentation target package: " + ii.targetPackage);
12454 return false;
12455 }
12456
12457 int match = mContext.getPackageManager().checkSignatures(
12458 ii.targetPackage, ii.packageName);
12459 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12460 String msg = "Permission Denial: starting instrumentation "
12461 + className + " from pid="
12462 + Binder.getCallingPid()
12463 + ", uid=" + Binder.getCallingPid()
12464 + " not allowed because package " + ii.packageName
12465 + " does not have a signature matching the target "
12466 + ii.targetPackage;
12467 reportStartInstrumentationFailure(watcher, className, msg);
12468 throw new SecurityException(msg);
12469 }
12470
12471 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012472 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012473 ProcessRecord app = addAppLocked(ai);
12474 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012475 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012476 app.instrumentationProfileFile = profileFile;
12477 app.instrumentationArguments = arguments;
12478 app.instrumentationWatcher = watcher;
12479 app.instrumentationResultClass = className;
12480 Binder.restoreCallingIdentity(origId);
12481 }
12482
12483 return true;
12484 }
12485
12486 /**
12487 * Report errors that occur while attempting to start Instrumentation. Always writes the
12488 * error to the logs, but if somebody is watching, send the report there too. This enables
12489 * the "am" command to report errors with more information.
12490 *
12491 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12492 * @param cn The component name of the instrumentation.
12493 * @param report The error report.
12494 */
12495 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12496 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012497 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012498 try {
12499 if (watcher != null) {
12500 Bundle results = new Bundle();
12501 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12502 results.putString("Error", report);
12503 watcher.instrumentationStatus(cn, -1, results);
12504 }
12505 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012506 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012507 }
12508 }
12509
12510 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12511 if (app.instrumentationWatcher != null) {
12512 try {
12513 // NOTE: IInstrumentationWatcher *must* be oneway here
12514 app.instrumentationWatcher.instrumentationFinished(
12515 app.instrumentationClass,
12516 resultCode,
12517 results);
12518 } catch (RemoteException e) {
12519 }
12520 }
12521 app.instrumentationWatcher = null;
12522 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012523 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012524 app.instrumentationProfileFile = null;
12525 app.instrumentationArguments = null;
12526
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012527 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012528 }
12529
12530 public void finishInstrumentation(IApplicationThread target,
12531 int resultCode, Bundle results) {
12532 // Refuse possible leaked file descriptors
12533 if (results != null && results.hasFileDescriptors()) {
12534 throw new IllegalArgumentException("File descriptors passed in Intent");
12535 }
12536
12537 synchronized(this) {
12538 ProcessRecord app = getRecordForAppLocked(target);
12539 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012540 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012541 return;
12542 }
12543 final long origId = Binder.clearCallingIdentity();
12544 finishInstrumentationLocked(app, resultCode, results);
12545 Binder.restoreCallingIdentity(origId);
12546 }
12547 }
12548
12549 // =========================================================
12550 // CONFIGURATION
12551 // =========================================================
12552
12553 public ConfigurationInfo getDeviceConfigurationInfo() {
12554 ConfigurationInfo config = new ConfigurationInfo();
12555 synchronized (this) {
12556 config.reqTouchScreen = mConfiguration.touchscreen;
12557 config.reqKeyboardType = mConfiguration.keyboard;
12558 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012559 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12560 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012561 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12562 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012563 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12564 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012565 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12566 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012567 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012568 }
12569 return config;
12570 }
12571
12572 public Configuration getConfiguration() {
12573 Configuration ci;
12574 synchronized(this) {
12575 ci = new Configuration(mConfiguration);
12576 }
12577 return ci;
12578 }
12579
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012580 public void updatePersistentConfiguration(Configuration values) {
12581 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12582 "updateConfiguration()");
12583 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12584 "updateConfiguration()");
12585 if (values == null) {
12586 throw new NullPointerException("Configuration must not be null");
12587 }
12588
12589 synchronized(this) {
12590 final long origId = Binder.clearCallingIdentity();
12591 updateConfigurationLocked(values, null, true);
12592 Binder.restoreCallingIdentity(origId);
12593 }
12594 }
12595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012596 public void updateConfiguration(Configuration values) {
12597 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12598 "updateConfiguration()");
12599
12600 synchronized(this) {
12601 if (values == null && mWindowManager != null) {
12602 // sentinel: fetch the current configuration from the window manager
12603 values = mWindowManager.computeNewConfiguration();
12604 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012605
12606 if (mWindowManager != null) {
12607 mProcessList.applyDisplaySize(mWindowManager);
12608 }
12609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012610 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012611 if (values != null) {
12612 Settings.System.clearConfiguration(values);
12613 }
12614 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012615 Binder.restoreCallingIdentity(origId);
12616 }
12617 }
12618
12619 /**
12620 * Do either or both things: (1) change the current configuration, and (2)
12621 * make sure the given activity is running with the (now) current
12622 * configuration. Returns true if the activity has been left running, or
12623 * false if <var>starting</var> is being destroyed to match the new
12624 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012625 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012626 */
12627 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012628 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012629 int changes = 0;
12630
12631 boolean kept = true;
12632
12633 if (values != null) {
12634 Configuration newConfig = new Configuration(mConfiguration);
12635 changes = newConfig.updateFrom(values);
12636 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012637 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012638 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012639 }
12640
Doug Zongker2bec3d42009-12-04 12:52:44 -080012641 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012642
12643 if (values.locale != null) {
12644 saveLocaleLocked(values.locale,
12645 !values.locale.equals(mConfiguration.locale),
12646 values.userSetLocale);
12647 }
12648
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012649 mConfigurationSeq++;
12650 if (mConfigurationSeq <= 0) {
12651 mConfigurationSeq = 1;
12652 }
12653 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012654 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012655 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012656
12657 AttributeCache ac = AttributeCache.instance();
12658 if (ac != null) {
12659 ac.updateConfiguration(mConfiguration);
12660 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012661
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012662 // Make sure all resources in our process are updated
12663 // right now, so that anyone who is going to retrieve
12664 // resource values after we return will be sure to get
12665 // the new ones. This is especially important during
12666 // boot, where the first config change needs to guarantee
12667 // all resources have that config before following boot
12668 // code is executed.
12669 mSystemThread.applyConfigurationToResources(newConfig);
12670
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012671 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012672 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12673 msg.obj = new Configuration(mConfiguration);
12674 mHandler.sendMessage(msg);
12675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012676
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012677 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12678 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012679 try {
12680 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012681 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012682 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012683 app.thread.scheduleConfigurationChanged(mConfiguration);
12684 }
12685 } catch (Exception e) {
12686 }
12687 }
12688 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012689 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12690 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012691 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12692 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012693 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12694 broadcastIntentLocked(null, null,
12695 new Intent(Intent.ACTION_LOCALE_CHANGED),
12696 null, null, 0, null, null,
12697 null, false, false, MY_PID, Process.SYSTEM_UID);
12698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012699 }
12700 }
12701
12702 if (changes != 0 && starting == null) {
12703 // If the configuration changed, and the caller is not already
12704 // in the process of starting an activity, then find the top
12705 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012706 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012707 }
12708
12709 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012710 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012711 // And we need to make sure at this point that all other activities
12712 // are made visible with the correct configuration.
12713 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012714 }
12715
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012716 if (values != null && mWindowManager != null) {
12717 mWindowManager.setNewConfiguration(mConfiguration);
12718 }
12719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012720 return kept;
12721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012722
12723 /**
12724 * Save the locale. You must be inside a synchronized (this) block.
12725 */
12726 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12727 if(isDiff) {
12728 SystemProperties.set("user.language", l.getLanguage());
12729 SystemProperties.set("user.region", l.getCountry());
12730 }
12731
12732 if(isPersist) {
12733 SystemProperties.set("persist.sys.language", l.getLanguage());
12734 SystemProperties.set("persist.sys.country", l.getCountry());
12735 SystemProperties.set("persist.sys.localevar", l.getVariant());
12736 }
12737 }
12738
12739 // =========================================================
12740 // LIFETIME MANAGEMENT
12741 // =========================================================
12742
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012743 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12744 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012745 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012746 // This adjustment has already been computed. If we are calling
12747 // from the top, we may have already computed our adjustment with
12748 // an earlier hidden adjustment that isn't really for us... if
12749 // so, use the new hidden adjustment.
12750 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012751 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012752 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012753 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012754 }
12755
12756 if (app.thread == null) {
12757 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012758 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012759 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012760 }
12761
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012762 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12763 app.adjSource = null;
12764 app.adjTarget = null;
12765 app.empty = false;
12766 app.hidden = false;
12767
12768 final int activitiesSize = app.activities.size();
12769
Dianne Hackborn7d608422011-08-07 16:24:18 -070012770 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012771 // The max adjustment doesn't allow this app to be anything
12772 // below foreground, so it is not worth doing work for it.
12773 app.adjType = "fixed";
12774 app.adjSeq = mAdjSeq;
12775 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012776 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012777 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012778 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012779 // System process can do UI, and when they do we want to have
12780 // them trim their memory after the user leaves the UI. To
12781 // facilitate this, here we need to determine whether or not it
12782 // is currently showing UI.
12783 app.systemNoUi = true;
12784 if (app == TOP_APP) {
12785 app.systemNoUi = false;
12786 } else if (activitiesSize > 0) {
12787 for (int j = 0; j < activitiesSize; j++) {
12788 final ActivityRecord r = app.activities.get(j);
12789 if (r.visible) {
12790 app.systemNoUi = false;
12791 break;
12792 }
12793 }
12794 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012795 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012796 }
12797
12798 final boolean hadForegroundActivities = app.foregroundActivities;
12799
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012800 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012801 app.keeping = false;
12802 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012803
The Android Open Source Project4df24232009-03-05 14:34:35 -080012804 // Determine the importance of the process, starting with most
12805 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012806 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012807 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012808 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012809 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012810 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012811 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012812 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012813 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012814 } else if (app.instrumentationClass != null) {
12815 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012816 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012817 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012818 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012819 } else if (app.curReceiver != null ||
12820 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12821 // An app that is currently receiving a broadcast also
12822 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012823 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012824 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012825 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012826 } else if (app.executingServices.size() > 0) {
12827 // An app that is currently executing a service callback also
12828 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012829 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012830 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012831 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012832 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012833 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012834 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012835 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012836 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012837 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012838 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012839 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012840 // A very not-needed process. If this is lower in the lru list,
12841 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012842 adj = hiddenAdj;
12843 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012844 app.hidden = true;
12845 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012846 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012847 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012848
12849 // Examine all activities if not already foreground.
12850 if (!app.foregroundActivities && activitiesSize > 0) {
12851 for (int j = 0; j < activitiesSize; j++) {
12852 final ActivityRecord r = app.activities.get(j);
12853 if (r.visible) {
12854 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012855 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12856 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012857 app.adjType = "visible";
12858 }
12859 schedGroup = Process.THREAD_GROUP_DEFAULT;
12860 app.hidden = false;
12861 app.foregroundActivities = true;
12862 break;
12863 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12864 || r.state == ActivityState.STOPPING) {
12865 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012866 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12867 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012868 app.adjType = "stopping";
12869 }
12870 app.foregroundActivities = true;
12871 }
12872 }
12873 }
12874
Dianne Hackborn7d608422011-08-07 16:24:18 -070012875 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012876 if (app.foregroundServices) {
12877 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012878 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012879 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012880 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012881 } else if (app.forcingToForeground != null) {
12882 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012883 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012884 app.adjType = "force-foreground";
12885 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012886 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012887 }
12888 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012889
Dianne Hackborn7d608422011-08-07 16:24:18 -070012890 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012891 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012892 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012893 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12894 app.adjType = "heavy";
12895 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012896
Dianne Hackborn7d608422011-08-07 16:24:18 -070012897 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012898 // This process is hosting what we currently consider to be the
12899 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012900 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012901 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12902 app.adjType = "home";
12903 }
12904
Joe Onorato8a9b2202010-02-26 18:56:32 -080012905 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012906
The Android Open Source Project4df24232009-03-05 14:34:35 -080012907 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012908 // there are applications dependent on our services or providers, but
12909 // this gives us a baseline and makes sure we don't get into an
12910 // infinite recursion.
12911 app.adjSeq = mAdjSeq;
12912 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012913
Christopher Tate6fa95972009-06-05 18:43:55 -070012914 if (mBackupTarget != null && app == mBackupTarget.app) {
12915 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070012916 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012917 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070012918 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012919 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012920 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012921 }
12922 }
12923
Dianne Hackborn7d608422011-08-07 16:24:18 -070012924 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012925 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012926 final long now = SystemClock.uptimeMillis();
12927 // This process is more important if the top activity is
12928 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012929 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012930 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012931 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012932 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012933 if (app.hasShownUi) {
12934 // If this process has shown some UI, let it immediately
12935 // go to the LRU list because it may be pretty heavy with
12936 // UI stuff. We'll tag it with a label just to help
12937 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012938 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012939 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012940 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012941 } else {
12942 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12943 // This service has seen some activity within
12944 // recent memory, so we will keep its process ahead
12945 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012946 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
12947 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012948 app.adjType = "started-services";
12949 app.hidden = false;
12950 }
12951 }
12952 // If we have let the service slide into the background
12953 // state, still have some text describing what it is doing
12954 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012955 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012956 app.adjType = "started-bg-services";
12957 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012958 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012959 // Don't kill this process because it is doing work; it
12960 // has said it is doing work.
12961 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012962 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012963 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012964 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012965 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012966 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012967 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012968 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012969 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012970 // XXX should compute this based on the max of
12971 // all connected clients.
12972 ConnectionRecord cr = clist.get(i);
12973 if (cr.binding.client == app) {
12974 // Binding to ourself is not interesting.
12975 continue;
12976 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012977 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012978 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012979 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012980 int myHiddenAdj = hiddenAdj;
12981 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012982 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012983 myHiddenAdj = client.hiddenAdj;
12984 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012985 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012986 }
12987 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012988 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012989 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012990 String adjType = null;
12991 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12992 // Not doing bind OOM management, so treat
12993 // this guy more like a started service.
12994 if (app.hasShownUi) {
12995 // If this process has shown some UI, let it immediately
12996 // go to the LRU list because it may be pretty heavy with
12997 // UI stuff. We'll tag it with a label just to help
12998 // debug and understand what is going on.
12999 if (adj > clientAdj) {
13000 adjType = "bound-bg-ui-services";
13001 }
13002 clientAdj = adj;
13003 } else {
13004 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13005 // This service has not seen activity within
13006 // recent memory, so allow it to drop to the
13007 // LRU list if there is no other reason to keep
13008 // it around. We'll also tag it with a label just
13009 // to help debug and undertand what is going on.
13010 if (adj > clientAdj) {
13011 adjType = "bound-bg-services";
13012 }
13013 clientAdj = adj;
13014 }
13015 }
13016 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013017 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013018 // If this process has recently shown UI, and
13019 // the process that is binding to it is less
13020 // important than being visible, then we don't
13021 // care about the binding as much as we care
13022 // about letting this process get into the LRU
13023 // list to be killed and restarted if needed for
13024 // memory.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013025 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013026 adjType = "bound-bg-ui-services";
13027 } else {
13028 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13029 |Context.BIND_IMPORTANT)) != 0) {
13030 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013031 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013032 adj = clientAdj;
13033 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013034 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013035 }
13036 if (!client.hidden) {
13037 app.hidden = false;
13038 }
13039 if (client.keeping) {
13040 app.keeping = true;
13041 }
13042 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013043 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013044 }
13045 if (adjType != null) {
13046 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013047 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13048 .REASON_SERVICE_IN_USE;
13049 app.adjSource = cr.binding.client;
13050 app.adjTarget = s.name;
13051 }
13052 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13053 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13054 schedGroup = Process.THREAD_GROUP_DEFAULT;
13055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013056 }
13057 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013058 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13059 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013060 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013061 (a.visible || a.state == ActivityState.RESUMED
13062 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013063 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013064 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13065 schedGroup = Process.THREAD_GROUP_DEFAULT;
13066 }
13067 app.hidden = false;
13068 app.adjType = "service";
13069 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13070 .REASON_SERVICE_IN_USE;
13071 app.adjSource = a;
13072 app.adjTarget = s.name;
13073 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013074 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013075 }
13076 }
13077 }
13078 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013079
Dianne Hackborn287952c2010-09-22 22:34:31 -070013080 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013081 // would like to avoid killing it unless it would prevent the current
13082 // application from running. By default we put the process in
13083 // with the rest of the background processes; as we scan through
13084 // its services we may bump it up from there.
13085 if (adj > hiddenAdj) {
13086 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013087 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013088 app.adjType = "bg-services";
13089 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013090 }
13091
Dianne Hackborn7d608422011-08-07 16:24:18 -070013092 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013093 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013094 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013095 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013096 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013097 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013098 if (cpr.clients.size() != 0) {
13099 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013100 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013101 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013102 if (client == app) {
13103 // Being our own client is not interesting.
13104 continue;
13105 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013106 int myHiddenAdj = hiddenAdj;
13107 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013108 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013109 myHiddenAdj = client.hiddenAdj;
13110 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013111 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013112 }
13113 }
13114 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013115 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013116 if (adj > clientAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013117 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013118 app.adjType = "bg-ui-provider";
13119 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013120 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13121 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013122 app.adjType = "provider";
13123 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013124 if (!client.hidden) {
13125 app.hidden = false;
13126 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013127 if (client.keeping) {
13128 app.keeping = true;
13129 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013130 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13131 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013132 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013133 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013134 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013135 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13136 schedGroup = Process.THREAD_GROUP_DEFAULT;
13137 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013138 }
13139 }
13140 // If the provider has external (non-framework) process
13141 // dependencies, ensure that its adjustment is at least
13142 // FOREGROUND_APP_ADJ.
13143 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013144 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13145 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013146 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013147 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013148 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013149 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013150 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013151 }
13152 }
13153 }
13154 }
13155
13156 app.curRawAdj = adj;
13157
Joe Onorato8a9b2202010-02-26 18:56:32 -080013158 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013159 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13160 if (adj > app.maxAdj) {
13161 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013162 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013163 schedGroup = Process.THREAD_GROUP_DEFAULT;
13164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013165 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013166 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013167 app.keeping = true;
13168 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013169
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013170 if (app.hasAboveClient) {
13171 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13172 // then we need to drop its adjustment to be lower than the service's
13173 // in order to honor the request. We want to drop it by one adjustment
13174 // level... but there is special meaning applied to various levels so
13175 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013176 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013177 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013178 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13179 adj = ProcessList.VISIBLE_APP_ADJ;
13180 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13181 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13182 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13183 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13184 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013185 adj++;
13186 }
13187 }
13188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013189 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013190 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013191
13192 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013193 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13194 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013195 }
13196
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013197 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013198 }
13199
13200 /**
13201 * Ask a given process to GC right now.
13202 */
13203 final void performAppGcLocked(ProcessRecord app) {
13204 try {
13205 app.lastRequestedGc = SystemClock.uptimeMillis();
13206 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013207 if (app.reportLowMemory) {
13208 app.reportLowMemory = false;
13209 app.thread.scheduleLowMemory();
13210 } else {
13211 app.thread.processInBackground();
13212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013213 }
13214 } catch (Exception e) {
13215 // whatever.
13216 }
13217 }
13218
13219 /**
13220 * Returns true if things are idle enough to perform GCs.
13221 */
Josh Bartel7f208742010-02-25 11:01:44 -060013222 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013223 return mParallelBroadcasts.size() == 0
13224 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013225 && (mSleeping || (mMainStack.mResumedActivity != null &&
13226 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013227 }
13228
13229 /**
13230 * Perform GCs on all processes that are waiting for it, but only
13231 * if things are idle.
13232 */
13233 final void performAppGcsLocked() {
13234 final int N = mProcessesToGc.size();
13235 if (N <= 0) {
13236 return;
13237 }
Josh Bartel7f208742010-02-25 11:01:44 -060013238 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013239 while (mProcessesToGc.size() > 0) {
13240 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013241 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013242 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13243 <= SystemClock.uptimeMillis()) {
13244 // To avoid spamming the system, we will GC processes one
13245 // at a time, waiting a few seconds between each.
13246 performAppGcLocked(proc);
13247 scheduleAppGcsLocked();
13248 return;
13249 } else {
13250 // It hasn't been long enough since we last GCed this
13251 // process... put it in the list to wait for its time.
13252 addProcessToGcListLocked(proc);
13253 break;
13254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013255 }
13256 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013257
13258 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013259 }
13260 }
13261
13262 /**
13263 * If all looks good, perform GCs on all processes waiting for them.
13264 */
13265 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013266 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013267 performAppGcsLocked();
13268 return;
13269 }
13270 // Still not idle, wait some more.
13271 scheduleAppGcsLocked();
13272 }
13273
13274 /**
13275 * Schedule the execution of all pending app GCs.
13276 */
13277 final void scheduleAppGcsLocked() {
13278 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013279
13280 if (mProcessesToGc.size() > 0) {
13281 // Schedule a GC for the time to the next process.
13282 ProcessRecord proc = mProcessesToGc.get(0);
13283 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13284
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013285 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013286 long now = SystemClock.uptimeMillis();
13287 if (when < (now+GC_TIMEOUT)) {
13288 when = now + GC_TIMEOUT;
13289 }
13290 mHandler.sendMessageAtTime(msg, when);
13291 }
13292 }
13293
13294 /**
13295 * Add a process to the array of processes waiting to be GCed. Keeps the
13296 * list in sorted order by the last GC time. The process can't already be
13297 * on the list.
13298 */
13299 final void addProcessToGcListLocked(ProcessRecord proc) {
13300 boolean added = false;
13301 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13302 if (mProcessesToGc.get(i).lastRequestedGc <
13303 proc.lastRequestedGc) {
13304 added = true;
13305 mProcessesToGc.add(i+1, proc);
13306 break;
13307 }
13308 }
13309 if (!added) {
13310 mProcessesToGc.add(0, proc);
13311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013312 }
13313
13314 /**
13315 * Set up to ask a process to GC itself. This will either do it
13316 * immediately, or put it on the list of processes to gc the next
13317 * time things are idle.
13318 */
13319 final void scheduleAppGcLocked(ProcessRecord app) {
13320 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013321 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013322 return;
13323 }
13324 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013325 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013326 scheduleAppGcsLocked();
13327 }
13328 }
13329
Dianne Hackborn287952c2010-09-22 22:34:31 -070013330 final void checkExcessivePowerUsageLocked(boolean doKills) {
13331 updateCpuStatsNow();
13332
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013333 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013334 boolean doWakeKills = doKills;
13335 boolean doCpuKills = doKills;
13336 if (mLastPowerCheckRealtime == 0) {
13337 doWakeKills = false;
13338 }
13339 if (mLastPowerCheckUptime == 0) {
13340 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013341 }
13342 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013343 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013344 }
13345 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013346 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13347 final long curUptime = SystemClock.uptimeMillis();
13348 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13349 mLastPowerCheckRealtime = curRealtime;
13350 mLastPowerCheckUptime = curUptime;
13351 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13352 doWakeKills = false;
13353 }
13354 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13355 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013356 }
13357 int i = mLruProcesses.size();
13358 while (i > 0) {
13359 i--;
13360 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013361 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013362 long wtime;
13363 synchronized (stats) {
13364 wtime = stats.getProcessWakeTime(app.info.uid,
13365 app.pid, curRealtime);
13366 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013367 long wtimeUsed = wtime - app.lastWakeTime;
13368 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13369 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013370 StringBuilder sb = new StringBuilder(128);
13371 sb.append("Wake for ");
13372 app.toShortString(sb);
13373 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013374 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013375 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013376 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013377 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013378 sb.append((wtimeUsed*100)/realtimeSince);
13379 sb.append("%)");
13380 Slog.i(TAG, sb.toString());
13381 sb.setLength(0);
13382 sb.append("CPU for ");
13383 app.toShortString(sb);
13384 sb.append(": over ");
13385 TimeUtils.formatDuration(uptimeSince, sb);
13386 sb.append(" used ");
13387 TimeUtils.formatDuration(cputimeUsed, sb);
13388 sb.append(" (");
13389 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013390 sb.append("%)");
13391 Slog.i(TAG, sb.toString());
13392 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013393 // If a process has held a wake lock for more
13394 // than 50% of the time during this period,
13395 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013396 if (doWakeKills && realtimeSince > 0
13397 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13398 synchronized (stats) {
13399 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13400 realtimeSince, wtimeUsed);
13401 }
13402 Slog.w(TAG, "Excessive wake lock in " + app.processName
13403 + " (pid " + app.pid + "): held " + wtimeUsed
13404 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013405 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13406 app.processName, app.setAdj, "excessive wake lock");
13407 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013408 } else if (doCpuKills && uptimeSince > 0
13409 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13410 synchronized (stats) {
13411 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13412 uptimeSince, cputimeUsed);
13413 }
13414 Slog.w(TAG, "Excessive CPU in " + app.processName
13415 + " (pid " + app.pid + "): used " + cputimeUsed
13416 + " during " + uptimeSince);
13417 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13418 app.processName, app.setAdj, "excessive cpu");
13419 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013420 } else {
13421 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013422 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013423 }
13424 }
13425 }
13426 }
13427
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013428 private final void updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013429 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013430 app.hiddenAdj = hiddenAdj;
13431
13432 if (app.thread == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013433 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013434 }
13435
Dianne Hackborn287952c2010-09-22 22:34:31 -070013436 final boolean wasKeeping = app.keeping;
13437
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013438 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013439
Jeff Brown10e89712011-07-08 18:52:57 -070013440 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013441 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13442 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013443 // If this app is transitioning from foreground to
13444 // non-foreground, have it do a gc.
13445 scheduleAppGcLocked(app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013446 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13447 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013448 // Likewise do a gc when an app is moving in to the
13449 // background (such as a service stopping).
13450 scheduleAppGcLocked(app);
13451 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013452
Jeff Brown10e89712011-07-08 18:52:57 -070013453 if (wasKeeping && !app.keeping) {
13454 // This app is no longer something we want to keep. Note
13455 // its current wake lock time to later know to kill it if
13456 // it is not behaving well.
13457 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13458 synchronized (stats) {
13459 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13460 app.pid, SystemClock.elapsedRealtime());
13461 }
13462 app.lastCpuTime = app.curCpuTime;
13463 }
13464
13465 app.setRawAdj = app.curRawAdj;
13466 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013467 if (app.curAdj != app.setAdj) {
13468 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013469 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13470 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013471 " oom adj to " + app.curAdj + " because " + app.adjType);
13472 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013473 } else {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013474 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013475 }
13476 }
13477 if (app.setSchedGroup != app.curSchedGroup) {
13478 app.setSchedGroup = app.curSchedGroup;
13479 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13480 "Setting process group of " + app.processName
13481 + " to " + app.curSchedGroup);
13482 if (app.waitingToKill != null &&
13483 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13484 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13485 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13486 app.processName, app.setAdj, app.waitingToKill);
13487 Process.killProcessQuiet(app.pid);
13488 } else {
13489 if (true) {
13490 long oldId = Binder.clearCallingIdentity();
13491 try {
13492 Process.setProcessGroup(app.pid, app.curSchedGroup);
13493 } catch (Exception e) {
13494 Slog.w(TAG, "Failed setting process group of " + app.pid
13495 + " to " + app.curSchedGroup);
13496 e.printStackTrace();
13497 } finally {
13498 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013499 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013500 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013501 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013502 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013503 app.thread.setSchedulingGroup(app.curSchedGroup);
13504 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013505 }
13506 }
13507 }
13508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013510 }
13511
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013512 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013513 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013514 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013515 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013516 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013517 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013518 }
13519 }
13520 return resumedActivity;
13521 }
13522
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013523 private final void updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013524 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013525 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13526 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013527 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13528 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013529
13530 mAdjSeq++;
13531
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013532 updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013533 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13534 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013535 if (nowHidden != wasHidden) {
13536 // Changed to/from hidden state, so apps after it in the LRU
13537 // list may also be changed.
13538 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013540 }
13541
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013542 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013543 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013544 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13545
13546 if (false) {
13547 RuntimeException e = new RuntimeException();
13548 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013549 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013550 }
13551
13552 mAdjSeq++;
13553
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013554 // Let's determine how many processes we have running vs.
13555 // how many slots we have for background processes; we may want
13556 // to put multiple processes in a slot of there are enough of
13557 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013558 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013559 int factor = (mLruProcesses.size()-4)/numSlots;
13560 if (factor < 1) factor = 1;
13561 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013562 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013563
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013564 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013565 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013566 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013567 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013568 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013569 while (i > 0) {
13570 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013571 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013572 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013573 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013574 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013575 && app.curAdj == curHiddenAdj) {
13576 step++;
13577 if (step >= factor) {
13578 step = 0;
13579 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013580 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013581 }
13582 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013583 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013584 numHidden++;
13585 if (numHidden > mProcessLimit) {
13586 Slog.i(TAG, "No longer want " + app.processName
13587 + " (pid " + app.pid + "): hidden #" + numHidden);
13588 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13589 app.processName, app.setAdj, "too many background");
13590 app.killedBackground = true;
13591 Process.killProcessQuiet(app.pid);
13592 } else {
13593 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013594 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013595 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013596 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013597 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013598 }
13599 }
13600
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013601 // Now determine the memory trimming level of background processes.
13602 // Unfortunately we need to start at the back of the list to do this
13603 // properly. We only do this if the number of background apps we
13604 // are managing to keep around is less than half the maximum we desire;
13605 // if we are keeping a good number around, we'll let them use whatever
13606 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013607 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013608 final int N = mLruProcesses.size();
13609 factor = numBg/3;
13610 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013611 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013612 for (i=0; i<N; i++) {
13613 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013614 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013615 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13616 try {
13617 app.thread.scheduleTrimMemory(curLevel);
13618 } catch (RemoteException e) {
13619 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013620 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013621 // For these apps we will also finish their activities
13622 // to help them free memory.
13623 mMainStack.destroyActivitiesLocked(app, false);
13624 }
13625 }
13626 app.trimMemoryLevel = curLevel;
13627 step++;
13628 if (step >= factor) {
13629 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013630 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13631 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013632 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013633 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13634 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013635 break;
13636 }
13637 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013638 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013639 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013640 && app.thread != null) {
13641 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013642 app.thread.scheduleTrimMemory(
13643 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013644 } catch (RemoteException e) {
13645 }
13646 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013647 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013648 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013649 && app.pendingUiClean) {
13650 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13651 && app.thread != null) {
13652 try {
13653 app.thread.scheduleTrimMemory(
13654 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13655 } catch (RemoteException e) {
13656 }
13657 }
13658 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13659 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013660 } else {
13661 app.trimMemoryLevel = 0;
13662 }
13663 }
13664 } else {
13665 final int N = mLruProcesses.size();
13666 for (i=0; i<N; i++) {
13667 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013668 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013669 && app.pendingUiClean) {
13670 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13671 && app.thread != null) {
13672 try {
13673 app.thread.scheduleTrimMemory(
13674 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13675 } catch (RemoteException e) {
13676 }
13677 }
13678 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13679 app.pendingUiClean = false;
13680 } else {
13681 app.trimMemoryLevel = 0;
13682 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013683 }
13684 }
13685
13686 if (mAlwaysFinishActivities) {
13687 mMainStack.destroyActivitiesLocked(null, false);
13688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013689 }
13690
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013691 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013692 synchronized (this) {
13693 int i;
13694
13695 // First remove any unused application processes whose package
13696 // has been removed.
13697 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13698 final ProcessRecord app = mRemovedProcesses.get(i);
13699 if (app.activities.size() == 0
13700 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013701 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013702 TAG, "Exiting empty application process "
13703 + app.processName + " ("
13704 + (app.thread != null ? app.thread.asBinder() : null)
13705 + ")\n");
13706 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013707 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13708 app.processName, app.setAdj, "empty");
13709 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013710 } else {
13711 try {
13712 app.thread.scheduleExit();
13713 } catch (Exception e) {
13714 // Ignore exceptions.
13715 }
13716 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013717 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013718 mRemovedProcesses.remove(i);
13719
13720 if (app.persistent) {
13721 if (app.persistent) {
13722 addAppLocked(app.info);
13723 }
13724 }
13725 }
13726 }
13727
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013728 // Now update the oom adj for all processes.
13729 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013730 }
13731 }
13732
13733 /** This method sends the specified signal to each of the persistent apps */
13734 public void signalPersistentProcesses(int sig) throws RemoteException {
13735 if (sig != Process.SIGNAL_USR1) {
13736 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13737 }
13738
13739 synchronized (this) {
13740 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13741 != PackageManager.PERMISSION_GRANTED) {
13742 throw new SecurityException("Requires permission "
13743 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13744 }
13745
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013746 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13747 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013748 if (r.thread != null && r.persistent) {
13749 Process.sendSignal(r.pid, sig);
13750 }
13751 }
13752 }
13753 }
13754
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013755 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13756 if (proc == null || proc == mProfileProc) {
13757 proc = mProfileProc;
13758 path = mProfileFile;
13759 profileType = mProfileType;
13760 clearProfilerLocked();
13761 }
13762 if (proc == null) {
13763 return;
13764 }
13765 try {
13766 proc.thread.profilerControl(false, path, null, profileType);
13767 } catch (RemoteException e) {
13768 throw new IllegalStateException("Process disappeared");
13769 }
13770 }
13771
13772 private void clearProfilerLocked() {
13773 if (mProfileFd != null) {
13774 try {
13775 mProfileFd.close();
13776 } catch (IOException e) {
13777 }
13778 }
13779 mProfileApp = null;
13780 mProfileProc = null;
13781 mProfileFile = null;
13782 mProfileType = 0;
13783 mAutoStopProfiler = false;
13784 }
13785
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013786 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013787 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013788
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013789 try {
13790 synchronized (this) {
13791 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13792 // its own permission.
13793 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13794 != PackageManager.PERMISSION_GRANTED) {
13795 throw new SecurityException("Requires permission "
13796 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013797 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013798
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013799 if (start && fd == null) {
13800 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013801 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013802
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013803 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013804 if (process != null) {
13805 try {
13806 int pid = Integer.parseInt(process);
13807 synchronized (mPidsSelfLocked) {
13808 proc = mPidsSelfLocked.get(pid);
13809 }
13810 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013811 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013812
13813 if (proc == null) {
13814 HashMap<String, SparseArray<ProcessRecord>> all
13815 = mProcessNames.getMap();
13816 SparseArray<ProcessRecord> procs = all.get(process);
13817 if (procs != null && procs.size() > 0) {
13818 proc = procs.valueAt(0);
13819 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013820 }
13821 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013822
13823 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013824 throw new IllegalArgumentException("Unknown process: " + process);
13825 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013826
13827 if (start) {
13828 stopProfilerLocked(null, null, 0);
13829 setProfileApp(proc.info, proc.processName, path, fd, false);
13830 mProfileProc = proc;
13831 mProfileType = profileType;
13832 try {
13833 fd = fd.dup();
13834 } catch (IOException e) {
13835 fd = null;
13836 }
13837 proc.thread.profilerControl(start, path, fd, profileType);
13838 fd = null;
13839 mProfileFd = null;
13840 } else {
13841 stopProfilerLocked(proc, path, profileType);
13842 if (fd != null) {
13843 try {
13844 fd.close();
13845 } catch (IOException e) {
13846 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013847 }
13848 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013849
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013850 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013851 }
13852 } catch (RemoteException e) {
13853 throw new IllegalStateException("Process disappeared");
13854 } finally {
13855 if (fd != null) {
13856 try {
13857 fd.close();
13858 } catch (IOException e) {
13859 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013860 }
13861 }
13862 }
Andy McFadden824c5102010-07-09 16:26:57 -070013863
13864 public boolean dumpHeap(String process, boolean managed,
13865 String path, ParcelFileDescriptor fd) throws RemoteException {
13866
13867 try {
13868 synchronized (this) {
13869 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13870 // its own permission (same as profileControl).
13871 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13872 != PackageManager.PERMISSION_GRANTED) {
13873 throw new SecurityException("Requires permission "
13874 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13875 }
13876
13877 if (fd == null) {
13878 throw new IllegalArgumentException("null fd");
13879 }
13880
13881 ProcessRecord proc = null;
13882 try {
13883 int pid = Integer.parseInt(process);
13884 synchronized (mPidsSelfLocked) {
13885 proc = mPidsSelfLocked.get(pid);
13886 }
13887 } catch (NumberFormatException e) {
13888 }
13889
13890 if (proc == null) {
13891 HashMap<String, SparseArray<ProcessRecord>> all
13892 = mProcessNames.getMap();
13893 SparseArray<ProcessRecord> procs = all.get(process);
13894 if (procs != null && procs.size() > 0) {
13895 proc = procs.valueAt(0);
13896 }
13897 }
13898
13899 if (proc == null || proc.thread == null) {
13900 throw new IllegalArgumentException("Unknown process: " + process);
13901 }
13902
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013903 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13904 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013905 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13906 throw new SecurityException("Process not debuggable: " + proc);
13907 }
13908 }
13909
13910 proc.thread.dumpHeap(managed, path, fd);
13911 fd = null;
13912 return true;
13913 }
13914 } catch (RemoteException e) {
13915 throw new IllegalStateException("Process disappeared");
13916 } finally {
13917 if (fd != null) {
13918 try {
13919 fd.close();
13920 } catch (IOException e) {
13921 }
13922 }
13923 }
13924 }
13925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013926 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13927 public void monitor() {
13928 synchronized (this) { }
13929 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013930
13931 public void onCoreSettingsChange(Bundle settings) {
13932 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13933 ProcessRecord processRecord = mLruProcesses.get(i);
13934 try {
13935 if (processRecord.thread != null) {
13936 processRecord.thread.setCoreSettings(settings);
13937 }
13938 } catch (RemoteException re) {
13939 /* ignore */
13940 }
13941 }
13942 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013943
13944 // Multi-user methods
13945
13946 public boolean switchUser(int userid) {
13947 // TODO
13948 return true;
13949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013950}