blob: 33a4e51012d7b3cff96bc0e1633fe7b350f998f8 [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 Hackborn860755f2010-06-03 18:47:52 -0700575 final HashMap<String, ContentProviderRecord> mProvidersByClass
576 = new HashMap<String, 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) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002702 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002703 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002704 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002705 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2706 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002707 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002708 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2709 // The low memory report is overriding any current
2710 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002711 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002712 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002713 rec.lastRequestedGc = 0;
2714 } else {
2715 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002717 rec.reportLowMemory = true;
2718 rec.lastLowMemory = now;
2719 mProcessesToGc.remove(rec);
2720 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721 }
2722 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002723 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 }
2725 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002726 } else if (app.pid != pid) {
2727 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002728 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002729 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002730 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002731 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002732 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 + thread.asBinder());
2734 }
2735 }
2736
Dan Egnor42471dd2010-01-07 17:25:22 -08002737 /**
2738 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002739 * @param clearTraces causes the dump file to be erased prior to the new
2740 * traces being written, if true; when false, the new traces will be
2741 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002742 * @param firstPids of dalvik VM processes to dump stack traces for first
2743 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002744 * @return file containing stack traces, or null if no dump file is configured
2745 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002746 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2747 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002748 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2749 if (tracesPath == null || tracesPath.length() == 0) {
2750 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002752
2753 File tracesFile = new File(tracesPath);
2754 try {
2755 File tracesDir = tracesFile.getParentFile();
2756 if (!tracesDir.exists()) tracesFile.mkdirs();
2757 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2758
Christopher Tate6ee412d2010-05-28 12:01:56 -07002759 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002760 tracesFile.createNewFile();
2761 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2762 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002763 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002764 return null;
2765 }
2766
2767 // Use a FileObserver to detect when traces finish writing.
2768 // The order of traces is considered important to maintain for legibility.
2769 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2770 public synchronized void onEvent(int event, String path) { notify(); }
2771 };
2772
2773 try {
2774 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002775
2776 // First collect all of the stacks of the most important pids.
2777 try {
2778 int num = firstPids.size();
2779 for (int i = 0; i < num; i++) {
2780 synchronized (observer) {
2781 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2782 observer.wait(200); // Wait for write-close, give up after 200msec
2783 }
2784 }
2785 } catch (InterruptedException e) {
2786 Log.wtf(TAG, e);
2787 }
2788
2789 // Next measure CPU usage.
2790 if (processStats != null) {
2791 processStats.init();
2792 System.gc();
2793 processStats.update();
2794 try {
2795 synchronized (processStats) {
2796 processStats.wait(500); // measure over 1/2 second.
2797 }
2798 } catch (InterruptedException e) {
2799 }
2800 processStats.update();
2801
2802 // We'll take the stack crawls of just the top apps using CPU.
2803 final int N = processStats.countWorkingStats();
2804 int numProcs = 0;
2805 for (int i=0; i<N && numProcs<5; i++) {
2806 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2807 if (lastPids.indexOfKey(stats.pid) >= 0) {
2808 numProcs++;
2809 try {
2810 synchronized (observer) {
2811 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2812 observer.wait(200); // Wait for write-close, give up after 200msec
2813 }
2814 } catch (InterruptedException e) {
2815 Log.wtf(TAG, e);
2816 }
2817
2818 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002819 }
2820 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002821
2822 return tracesFile;
2823
Dan Egnor42471dd2010-01-07 17:25:22 -08002824 } finally {
2825 observer.stopWatching();
2826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827 }
2828
Jeff Brown4d94a762010-09-23 11:33:28 -07002829 private final class AppNotResponding implements Runnable {
2830 private final ProcessRecord mApp;
2831 private final String mAnnotation;
2832
2833 public AppNotResponding(ProcessRecord app, String annotation) {
2834 mApp = app;
2835 mAnnotation = annotation;
2836 }
2837
2838 @Override
2839 public void run() {
2840 appNotResponding(mApp, null, null, mAnnotation);
2841 }
2842 }
2843
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002844 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2845 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002846 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2847 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2848
Dianne Hackborn287952c2010-09-22 22:34:31 -07002849 if (mController != null) {
2850 try {
2851 // 0 == continue, -1 = kill process immediately
2852 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2853 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2854 } catch (RemoteException e) {
2855 mController = null;
2856 }
2857 }
2858
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002859 long anrTime = SystemClock.uptimeMillis();
2860 if (MONITOR_CPU_USAGE) {
2861 updateCpuStatsNow();
2862 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002863
2864 synchronized (this) {
2865 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2866 if (mShuttingDown) {
2867 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2868 return;
2869 } else if (app.notResponding) {
2870 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2871 return;
2872 } else if (app.crashing) {
2873 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2874 return;
2875 }
2876
2877 // In case we come through here for the same app before completing
2878 // this one, mark as anring now so we will bail out.
2879 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002880
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002881 // Log the ANR to the event log.
2882 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2883 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002884
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002885 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002886 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002887
2888 int parentPid = app.pid;
2889 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002890 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002891
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002892 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002893
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002894 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2895 ProcessRecord r = mLruProcesses.get(i);
2896 if (r != null && r.thread != null) {
2897 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002898 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2899 if (r.persistent) {
2900 firstPids.add(pid);
2901 } else {
2902 lastPids.put(pid, Boolean.TRUE);
2903 }
2904 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 }
2907 }
2908
Dan Egnor42471dd2010-01-07 17:25:22 -08002909 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002910 StringBuilder info = mStringBuilder;
2911 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002912 info.append("ANR in ").append(app.processName);
2913 if (activity != null && activity.shortComponentName != null) {
2914 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002915 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002916 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002917 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002918 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002919 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002920 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002921 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923
Dianne Hackborn287952c2010-09-22 22:34:31 -07002924 final ProcessStats processStats = new ProcessStats(true);
2925
2926 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2927
Dan Egnor42471dd2010-01-07 17:25:22 -08002928 String cpuInfo = null;
2929 if (MONITOR_CPU_USAGE) {
2930 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002931 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002932 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002933 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002934 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002935 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936 }
2937
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002938 info.append(processStats.printCurrentState(anrTime));
2939
Joe Onorato8a9b2202010-02-26 18:56:32 -08002940 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002941 if (tracesFile == null) {
2942 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2943 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2944 }
2945
2946 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2947
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002948 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002949 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002950 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2951 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002952 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002953 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2954 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955 }
2956 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002957 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002958 }
2959 }
2960
Dan Egnor42471dd2010-01-07 17:25:22 -08002961 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2962 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2963 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002964
2965 synchronized (this) {
2966 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002967 Slog.w(TAG, "Killing " + app + ": background ANR");
2968 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
2969 app.processName, app.setAdj, "background ANR");
2970 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002971 return;
2972 }
2973
2974 // Set the app's notResponding state, and look up the errorReportReceiver
2975 makeAppNotRespondingLocked(app,
2976 activity != null ? activity.shortComponentName : null,
2977 annotation != null ? "ANR " + annotation : "ANR",
2978 info.toString());
2979
2980 // Bring up the infamous App Not Responding dialog
2981 Message msg = Message.obtain();
2982 HashMap map = new HashMap();
2983 msg.what = SHOW_NOT_RESPONDING_MSG;
2984 msg.obj = map;
2985 map.put("app", app);
2986 if (activity != null) {
2987 map.put("activity", activity);
2988 }
2989
2990 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08002991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 }
2993
Dianne Hackborn0dad3642010-09-09 21:25:35 -07002994 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
2995 if (!mLaunchWarningShown) {
2996 mLaunchWarningShown = true;
2997 mHandler.post(new Runnable() {
2998 @Override
2999 public void run() {
3000 synchronized (ActivityManagerService.this) {
3001 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3002 d.show();
3003 mHandler.postDelayed(new Runnable() {
3004 @Override
3005 public void run() {
3006 synchronized (ActivityManagerService.this) {
3007 d.dismiss();
3008 mLaunchWarningShown = false;
3009 }
3010 }
3011 }, 4000);
3012 }
3013 }
3014 });
3015 }
3016 }
3017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003018 public boolean clearApplicationUserData(final String packageName,
3019 final IPackageDataObserver observer) {
3020 int uid = Binder.getCallingUid();
3021 int pid = Binder.getCallingPid();
3022 long callingId = Binder.clearCallingIdentity();
3023 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003024 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 int pkgUid = -1;
3026 synchronized(this) {
3027 try {
3028 pkgUid = pm.getPackageUid(packageName);
3029 } catch (RemoteException e) {
3030 }
3031 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003032 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003033 return false;
3034 }
3035 if (uid == pkgUid || checkComponentPermission(
3036 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003037 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003039 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 } else {
3041 throw new SecurityException(pid+" does not have permission:"+
3042 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3043 "for process:"+packageName);
3044 }
3045 }
3046
3047 try {
3048 //clear application user data
3049 pm.clearApplicationUserData(packageName, observer);
3050 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3051 Uri.fromParts("package", packageName, null));
3052 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003053 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3054 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003055 } catch (RemoteException e) {
3056 }
3057 } finally {
3058 Binder.restoreCallingIdentity(callingId);
3059 }
3060 return true;
3061 }
3062
Dianne Hackborn03abb812010-01-04 18:43:19 -08003063 public void killBackgroundProcesses(final String packageName) {
3064 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3065 != PackageManager.PERMISSION_GRANTED &&
3066 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3067 != PackageManager.PERMISSION_GRANTED) {
3068 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 + Binder.getCallingPid()
3070 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003071 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003072 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 throw new SecurityException(msg);
3074 }
3075
3076 long callingId = Binder.clearCallingIdentity();
3077 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003078 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003079 int pkgUid = -1;
3080 synchronized(this) {
3081 try {
3082 pkgUid = pm.getPackageUid(packageName);
3083 } catch (RemoteException e) {
3084 }
3085 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003086 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003087 return;
3088 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003089 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn7d608422011-08-07 16:24:18 -07003090 ProcessList.SECONDARY_SERVER_ADJ, false, true, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003091 }
3092 } finally {
3093 Binder.restoreCallingIdentity(callingId);
3094 }
3095 }
3096
3097 public void forceStopPackage(final String packageName) {
3098 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3099 != PackageManager.PERMISSION_GRANTED) {
3100 String msg = "Permission Denial: forceStopPackage() from pid="
3101 + Binder.getCallingPid()
3102 + ", uid=" + Binder.getCallingUid()
3103 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003104 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003105 throw new SecurityException(msg);
3106 }
3107
3108 long callingId = Binder.clearCallingIdentity();
3109 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003110 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003111 int pkgUid = -1;
3112 synchronized(this) {
3113 try {
3114 pkgUid = pm.getPackageUid(packageName);
3115 } catch (RemoteException e) {
3116 }
3117 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003118 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003119 return;
3120 }
3121 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003122 try {
3123 pm.setPackageStoppedState(packageName, true);
3124 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003125 } catch (IllegalArgumentException e) {
3126 Slog.w(TAG, "Failed trying to unstop package "
3127 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003129 }
3130 } finally {
3131 Binder.restoreCallingIdentity(callingId);
3132 }
3133 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003134
3135 /*
3136 * The pkg name and uid have to be specified.
3137 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3138 */
3139 public void killApplicationWithUid(String pkg, int uid) {
3140 if (pkg == null) {
3141 return;
3142 }
3143 // Make sure the uid is valid.
3144 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003145 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003146 return;
3147 }
3148 int callerUid = Binder.getCallingUid();
3149 // Only the system server can kill an application
3150 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003151 // Post an aysnc message to kill the application
3152 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3153 msg.arg1 = uid;
3154 msg.arg2 = 0;
3155 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003156 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003157 } else {
3158 throw new SecurityException(callerUid + " cannot kill pkg: " +
3159 pkg);
3160 }
3161 }
3162
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003163 public void closeSystemDialogs(String reason) {
3164 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003165 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003166 if (reason != null) {
3167 intent.putExtra("reason", reason);
3168 }
3169
3170 final int uid = Binder.getCallingUid();
3171 final long origId = Binder.clearCallingIdentity();
3172 synchronized (this) {
3173 int i = mWatchers.beginBroadcast();
3174 while (i > 0) {
3175 i--;
3176 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3177 if (w != null) {
3178 try {
3179 w.closingSystemDialogs(reason);
3180 } catch (RemoteException e) {
3181 }
3182 }
3183 }
3184 mWatchers.finishBroadcast();
3185
Dianne Hackbornffa42482009-09-23 22:20:11 -07003186 mWindowManager.closeSystemDialogs(reason);
3187
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003188 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3189 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003190 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003191 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003192 Activity.RESULT_CANCELED, null, "close-sys");
3193 }
3194 }
3195
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003196 broadcastIntentLocked(null, null, intent, null,
3197 null, 0, null, null, null, false, false, -1, uid);
3198 }
3199 Binder.restoreCallingIdentity(origId);
3200 }
3201
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003202 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003203 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003204 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3205 for (int i=pids.length-1; i>=0; i--) {
3206 infos[i] = new Debug.MemoryInfo();
3207 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003208 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003209 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003210 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003211
Dianne Hackbornb437e092011-08-05 17:50:29 -07003212 public long[] getProcessPss(int[] pids) throws RemoteException {
3213 long[] pss = new long[pids.length];
3214 for (int i=pids.length-1; i>=0; i--) {
3215 pss[i] = Debug.getPss(pids[i]);
3216 }
3217 return pss;
3218 }
3219
Christopher Tate5e1ab332009-09-01 20:32:49 -07003220 public void killApplicationProcess(String processName, int uid) {
3221 if (processName == null) {
3222 return;
3223 }
3224
3225 int callerUid = Binder.getCallingUid();
3226 // Only the system server can kill an application
3227 if (callerUid == Process.SYSTEM_UID) {
3228 synchronized (this) {
3229 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003230 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003231 try {
3232 app.thread.scheduleSuicide();
3233 } catch (RemoteException e) {
3234 // If the other end already died, then our work here is done.
3235 }
3236 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003237 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003238 + processName + " / " + uid);
3239 }
3240 }
3241 } else {
3242 throw new SecurityException(callerUid + " cannot kill app process: " +
3243 processName);
3244 }
3245 }
3246
Dianne Hackborn03abb812010-01-04 18:43:19 -08003247 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003248 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003249 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3250 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003251 if (!mProcessesReady) {
3252 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003254 intent.putExtra(Intent.EXTRA_UID, uid);
3255 broadcastIntentLocked(null, null, intent,
3256 null, null, 0, null, null, null,
3257 false, false, MY_PID, Process.SYSTEM_UID);
3258 }
3259
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003260 private final boolean killPackageProcessesLocked(String packageName, int uid,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003261 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003262 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003263
Dianne Hackborn03abb812010-01-04 18:43:19 -08003264 // Remove all processes this package may have touched: all with the
3265 // same UID (except for the system or root user), and all whose name
3266 // matches the package name.
3267 final String procNamePrefix = packageName + ":";
3268 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3269 final int NA = apps.size();
3270 for (int ia=0; ia<NA; ia++) {
3271 ProcessRecord app = apps.valueAt(ia);
Christopher Tate064d8422011-07-26 15:38:07 -07003272 if (app.persistent) {
3273 // we don't kill persistent processes
3274 continue;
3275 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003276 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003277 if (doit) {
3278 procs.add(app);
3279 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003280 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3281 || app.processName.equals(packageName)
3282 || app.processName.startsWith(procNamePrefix)) {
3283 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003284 if (!doit) {
3285 return true;
3286 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003287 app.removed = true;
3288 procs.add(app);
3289 }
3290 }
3291 }
3292 }
3293
3294 int N = procs.size();
3295 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003296 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003297 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003298 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003299 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003300
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003301 private final boolean forceStopPackageLocked(String name, int uid,
3302 boolean callerWillRestart, boolean purgeCache, boolean doit) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003303 int i;
3304 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003306 if (uid < 0) {
3307 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003308 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003309 } catch (RemoteException e) {
3310 }
3311 }
3312
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003313 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003314 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003315
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003316 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3317 while (badApps.hasNext()) {
3318 SparseArray<Long> ba = badApps.next();
3319 if (ba.get(uid) != null) {
3320 badApps.remove();
3321 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003322 }
3323 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003324
3325 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003326 callerWillRestart, false, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003327
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003328 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3329 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Christopher Tate064d8422011-07-26 15:38:07 -07003330 if (r.packageName.equals(name)
3331 && (r.app == null || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003332 if (!doit) {
3333 return true;
3334 }
3335 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003336 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003337 if (r.app != null) {
3338 r.app.removed = true;
3339 }
3340 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003341 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003342 }
3343 }
3344
3345 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3346 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003347 if (service.packageName.equals(name)
3348 && (service.app == null || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003349 if (!doit) {
3350 return true;
3351 }
3352 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003353 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003354 if (service.app != null) {
3355 service.app.removed = true;
3356 }
3357 service.app = null;
3358 services.add(service);
3359 }
3360 }
3361
3362 N = services.size();
3363 for (i=0; i<N; i++) {
3364 bringDownServiceLocked(services.get(i), true);
3365 }
3366
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003367 if (doit) {
3368 if (purgeCache) {
3369 AttributeCache ac = AttributeCache.instance();
3370 if (ac != null) {
3371 ac.removePackage(name);
3372 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003373 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003374 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003375 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003376
3377 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003378 }
3379
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003380 private final boolean removeProcessLocked(ProcessRecord app,
3381 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003382 final String name = app.processName;
3383 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003384 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003385 TAG, "Force removing process " + app + " (" + name
3386 + "/" + uid + ")");
3387
3388 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003389 if (mHeavyWeightProcess == app) {
3390 mHeavyWeightProcess = null;
3391 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 boolean needRestart = false;
3394 if (app.pid > 0 && app.pid != MY_PID) {
3395 int pid = app.pid;
3396 synchronized (mPidsSelfLocked) {
3397 mPidsSelfLocked.remove(pid);
3398 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3399 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003400 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003401 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003402 Process.killProcess(pid);
3403
3404 if (app.persistent) {
3405 if (!callerWillRestart) {
3406 addAppLocked(app.info);
3407 } else {
3408 needRestart = true;
3409 }
3410 }
3411 } else {
3412 mRemovedProcesses.add(app);
3413 }
3414
3415 return needRestart;
3416 }
3417
3418 private final void processStartTimedOutLocked(ProcessRecord app) {
3419 final int pid = app.pid;
3420 boolean gone = false;
3421 synchronized (mPidsSelfLocked) {
3422 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3423 if (knownApp != null && knownApp.thread == null) {
3424 mPidsSelfLocked.remove(pid);
3425 gone = true;
3426 }
3427 }
3428
3429 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003430 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003431 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003432 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003433 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003434 if (mHeavyWeightProcess == app) {
3435 mHeavyWeightProcess = null;
3436 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3437 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003438 // Take care of any launching providers waiting for this process.
3439 checkAppInLaunchingProvidersLocked(app, true);
3440 // Take care of any services that are waiting for the process.
3441 for (int i=0; i<mPendingServices.size(); i++) {
3442 ServiceRecord sr = mPendingServices.get(i);
3443 if (app.info.uid == sr.appInfo.uid
3444 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003445 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003446 mPendingServices.remove(i);
3447 i--;
3448 bringDownServiceLocked(sr, true);
3449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003450 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003451 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3452 app.processName, app.setAdj, "start timeout");
3453 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003454 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003455 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003456 try {
3457 IBackupManager bm = IBackupManager.Stub.asInterface(
3458 ServiceManager.getService(Context.BACKUP_SERVICE));
3459 bm.agentDisconnected(app.info.packageName);
3460 } catch (RemoteException e) {
3461 // Can't happen; the backup manager is local
3462 }
3463 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003464 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003465 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003466 mPendingBroadcast.state = BroadcastRecord.IDLE;
3467 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003468 mPendingBroadcast = null;
3469 scheduleBroadcastsLocked();
3470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003471 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003472 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003473 }
3474 }
3475
3476 private final boolean attachApplicationLocked(IApplicationThread thread,
3477 int pid) {
3478
3479 // Find the application record that is being attached... either via
3480 // the pid if we are running in multiple processes, or just pull the
3481 // next app record if we are emulating process with anonymous threads.
3482 ProcessRecord app;
3483 if (pid != MY_PID && pid >= 0) {
3484 synchronized (mPidsSelfLocked) {
3485 app = mPidsSelfLocked.get(pid);
3486 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003487 } else {
3488 app = null;
3489 }
3490
3491 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003492 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003493 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003494 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003495 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003496 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003497 } else {
3498 try {
3499 thread.scheduleExit();
3500 } catch (Exception e) {
3501 // Ignore exceptions.
3502 }
3503 }
3504 return false;
3505 }
3506
3507 // If this application record is still attached to a previous
3508 // process, clean it up now.
3509 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003510 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003511 }
3512
3513 // Tell the process all about itself.
3514
Joe Onorato8a9b2202010-02-26 18:56:32 -08003515 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003516 TAG, "Binding process pid " + pid + " to record " + app);
3517
3518 String processName = app.processName;
3519 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003520 AppDeathRecipient adr = new AppDeathRecipient(
3521 app, pid, thread);
3522 thread.asBinder().linkToDeath(adr, 0);
3523 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003524 } catch (RemoteException e) {
3525 app.resetPackageList();
3526 startProcessLocked(app, "link fail", processName);
3527 return false;
3528 }
3529
Doug Zongker2bec3d42009-12-04 12:52:44 -08003530 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003531
3532 app.thread = thread;
3533 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003534 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3535 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003536 app.forcingToForeground = null;
3537 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003538 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003539 app.debugging = false;
3540
3541 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3542
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003543 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003544 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003545
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003546 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003547 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003548 }
3549
Joe Onorato8a9b2202010-02-26 18:56:32 -08003550 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003551 TAG, "New app record " + app
3552 + " thread=" + thread.asBinder() + " pid=" + pid);
3553 try {
3554 int testMode = IApplicationThread.DEBUG_OFF;
3555 if (mDebugApp != null && mDebugApp.equals(processName)) {
3556 testMode = mWaitForDebugger
3557 ? IApplicationThread.DEBUG_WAIT
3558 : IApplicationThread.DEBUG_ON;
3559 app.debugging = true;
3560 if (mDebugTransient) {
3561 mDebugApp = mOrigDebugApp;
3562 mWaitForDebugger = mOrigWaitForDebugger;
3563 }
3564 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003565 String profileFile = app.instrumentationProfileFile;
3566 ParcelFileDescriptor profileFd = null;
3567 boolean profileAutoStop = false;
3568 if (mProfileApp != null && mProfileApp.equals(processName)) {
3569 mProfileProc = app;
3570 profileFile = mProfileFile;
3571 profileFd = mProfileFd;
3572 profileAutoStop = mAutoStopProfiler;
3573 }
3574
Christopher Tate181fafa2009-05-14 11:12:14 -07003575 // If the app is being launched for restore or full backup, set it up specially
3576 boolean isRestrictedBackupMode = false;
3577 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3578 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003579 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003580 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3581 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003582
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003583 ensurePackageDexOpt(app.instrumentationInfo != null
3584 ? app.instrumentationInfo.packageName
3585 : app.info.packageName);
3586 if (app.instrumentationClass != null) {
3587 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003588 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003589 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003590 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003591 ApplicationInfo appInfo = app.instrumentationInfo != null
3592 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003593 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003594 if (profileFd != null) {
3595 profileFd = profileFd.dup();
3596 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003597 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003598 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003599 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003600 isRestrictedBackupMode || !normalMode,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003601 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003602 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003603 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003604 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003605 } catch (Exception e) {
3606 // todo: Yikes! What should we do? For now we will try to
3607 // start another process, but that could easily get us in
3608 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003609 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610
3611 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003612 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003613 startProcessLocked(app, "bind fail", processName);
3614 return false;
3615 }
3616
3617 // Remove this record from the list of starting applications.
3618 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003619 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3620 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003621 mProcessesOnHold.remove(app);
3622
3623 boolean badApp = false;
3624 boolean didSomething = false;
3625
3626 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003627 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003628 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3630 && processName.equals(hr.processName)) {
3631 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003632 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003633 didSomething = true;
3634 }
3635 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003636 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003637 + hr.intent.getComponent().flattenToShortString(), e);
3638 badApp = true;
3639 }
3640 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003641 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003642 }
3643 }
3644
3645 // Find any services that should be running in this process...
3646 if (!badApp && mPendingServices.size() > 0) {
3647 ServiceRecord sr = null;
3648 try {
3649 for (int i=0; i<mPendingServices.size(); i++) {
3650 sr = mPendingServices.get(i);
3651 if (app.info.uid != sr.appInfo.uid
3652 || !processName.equals(sr.processName)) {
3653 continue;
3654 }
3655
3656 mPendingServices.remove(i);
3657 i--;
3658 realStartServiceLocked(sr, app);
3659 didSomething = true;
3660 }
3661 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003662 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003663 + sr.shortName, e);
3664 badApp = true;
3665 }
3666 }
3667
3668 // Check if the next broadcast receiver is in this process...
3669 BroadcastRecord br = mPendingBroadcast;
3670 if (!badApp && br != null && br.curApp == app) {
3671 try {
3672 mPendingBroadcast = null;
3673 processCurBroadcastLocked(br, app);
3674 didSomething = true;
3675 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003676 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 + br.curComponent.flattenToShortString(), e);
3678 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003679 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3681 br.resultExtras, br.resultAbort, true);
3682 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003683 // We need to reset the state if we fails to start the receiver.
3684 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003685 }
3686 }
3687
Christopher Tate181fafa2009-05-14 11:12:14 -07003688 // Check whether the next backup agent is in this process...
3689 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003690 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003691 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003692 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003693 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3694 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3695 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003696 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003697 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003698 e.printStackTrace();
3699 }
3700 }
3701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003702 if (badApp) {
3703 // todo: Also need to kill application to deal with all
3704 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003705 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003706 return false;
3707 }
3708
3709 if (!didSomething) {
3710 updateOomAdjLocked();
3711 }
3712
3713 return true;
3714 }
3715
3716 public final void attachApplication(IApplicationThread thread) {
3717 synchronized (this) {
3718 int callingPid = Binder.getCallingPid();
3719 final long origId = Binder.clearCallingIdentity();
3720 attachApplicationLocked(thread, callingPid);
3721 Binder.restoreCallingIdentity(origId);
3722 }
3723 }
3724
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003725 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003726 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003727 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3728 if (stopProfiling) {
3729 synchronized (this) {
3730 if (mProfileProc == r.app) {
3731 if (mProfileFd != null) {
3732 try {
3733 mProfileFd.close();
3734 } catch (IOException e) {
3735 }
3736 clearProfilerLocked();
3737 }
3738 }
3739 }
3740 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003741 Binder.restoreCallingIdentity(origId);
3742 }
3743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003745 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003746 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003747 mWindowManager.enableScreenAfterBoot();
3748 }
3749
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003750 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003751 IntentFilter pkgFilter = new IntentFilter();
3752 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3753 pkgFilter.addDataScheme("package");
3754 mContext.registerReceiver(new BroadcastReceiver() {
3755 @Override
3756 public void onReceive(Context context, Intent intent) {
3757 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3758 if (pkgs != null) {
3759 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003760 synchronized (ActivityManagerService.this) {
3761 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3762 setResultCode(Activity.RESULT_OK);
3763 return;
3764 }
3765 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003766 }
3767 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003768 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003769 }, pkgFilter);
3770
3771 synchronized (this) {
3772 // Ensure that any processes we had put on hold are now started
3773 // up.
3774 final int NP = mProcessesOnHold.size();
3775 if (NP > 0) {
3776 ArrayList<ProcessRecord> procs =
3777 new ArrayList<ProcessRecord>(mProcessesOnHold);
3778 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003779 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3780 + procs.get(ip));
3781 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003782 }
3783 }
3784
3785 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003786 // Start looking for apps that are abusing wake locks.
3787 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003788 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003789 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003790 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003791 broadcastIntentLocked(null, null,
3792 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3793 null, null, 0, null, null,
3794 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3795 false, false, MY_PID, Process.SYSTEM_UID);
3796 }
3797 }
3798 }
3799
3800 final void ensureBootCompleted() {
3801 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003802 boolean enableScreen;
3803 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003804 booting = mBooting;
3805 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003806 enableScreen = !mBooted;
3807 mBooted = true;
3808 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003809
3810 if (booting) {
3811 finishBooting();
3812 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003813
3814 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003815 enableScreenAfterBoot();
3816 }
3817 }
3818
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003819 public final void activityPaused(IBinder token) {
3820 final long origId = Binder.clearCallingIdentity();
3821 mMainStack.activityPaused(token, false);
3822 Binder.restoreCallingIdentity(origId);
3823 }
3824
3825 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3826 CharSequence description) {
3827 if (localLOGV) Slog.v(
3828 TAG, "Activity stopped: token=" + token);
3829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003830 // Refuse possible leaked file descriptors
3831 if (icicle != null && icicle.hasFileDescriptors()) {
3832 throw new IllegalArgumentException("File descriptors passed in Bundle");
3833 }
3834
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003835 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836
3837 final long origId = Binder.clearCallingIdentity();
3838
3839 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003840 r = mMainStack.isInStackLocked(token);
3841 if (r != null) {
3842 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003843 }
3844 }
3845
3846 if (r != null) {
3847 sendPendingThumbnail(r, null, null, null, false);
3848 }
3849
3850 trimApplications();
3851
3852 Binder.restoreCallingIdentity(origId);
3853 }
3854
3855 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003856 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003857 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003858 }
3859
3860 public String getCallingPackage(IBinder token) {
3861 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003862 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003863 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 }
3865 }
3866
3867 public ComponentName getCallingActivity(IBinder token) {
3868 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003869 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003870 return r != null ? r.intent.getComponent() : null;
3871 }
3872 }
3873
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003874 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003875 ActivityRecord r = mMainStack.isInStackLocked(token);
3876 if (r == null) {
3877 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003878 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003879 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003880 }
3881
3882 public ComponentName getActivityClassForToken(IBinder token) {
3883 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003884 ActivityRecord r = mMainStack.isInStackLocked(token);
3885 if (r == null) {
3886 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003887 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003888 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889 }
3890 }
3891
3892 public String getPackageForToken(IBinder token) {
3893 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003894 ActivityRecord r = mMainStack.isInStackLocked(token);
3895 if (r == null) {
3896 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003897 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003898 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003899 }
3900 }
3901
3902 public IIntentSender getIntentSender(int type,
3903 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003904 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003906 if (intents != null) {
3907 if (intents.length < 1) {
3908 throw new IllegalArgumentException("Intents array length must be >= 1");
3909 }
3910 for (int i=0; i<intents.length; i++) {
3911 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003912 if (intent != null) {
3913 if (intent.hasFileDescriptors()) {
3914 throw new IllegalArgumentException("File descriptors passed in Intent");
3915 }
3916 if (type == INTENT_SENDER_BROADCAST &&
3917 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3918 throw new IllegalArgumentException(
3919 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3920 }
3921 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003922 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003923 }
3924 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003925 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003926 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003927 }
3928 }
3929
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003930 synchronized(this) {
3931 int callingUid = Binder.getCallingUid();
3932 try {
Jeff Brown10e89712011-07-08 18:52:57 -07003933 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003934 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003935 .getPackageUid(packageName);
3936 if (uid != Binder.getCallingUid()) {
3937 String msg = "Permission Denial: getIntentSender() from pid="
3938 + Binder.getCallingPid()
3939 + ", uid=" + Binder.getCallingUid()
3940 + ", (need uid=" + uid + ")"
3941 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003942 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003943 throw new SecurityException(msg);
3944 }
3945 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003946
3947 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003948 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003950 } catch (RemoteException e) {
3951 throw new SecurityException(e);
3952 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003953 }
3954 }
3955
3956 IIntentSender getIntentSenderLocked(int type,
3957 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003958 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003959 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003960 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003961 activity = mMainStack.isInStackLocked(token);
3962 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07003963 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003964 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003965 if (activity.finishing) {
3966 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003967 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003968 }
3969
3970 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3971 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3972 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3973 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3974 |PendingIntent.FLAG_UPDATE_CURRENT);
3975
3976 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3977 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003978 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003979 WeakReference<PendingIntentRecord> ref;
3980 ref = mIntentSenderRecords.get(key);
3981 PendingIntentRecord rec = ref != null ? ref.get() : null;
3982 if (rec != null) {
3983 if (!cancelCurrent) {
3984 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003985 if (rec.key.requestIntent != null) {
3986 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
3987 }
3988 if (intents != null) {
3989 intents[intents.length-1] = rec.key.requestIntent;
3990 rec.key.allIntents = intents;
3991 rec.key.allResolvedTypes = resolvedTypes;
3992 } else {
3993 rec.key.allIntents = null;
3994 rec.key.allResolvedTypes = null;
3995 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003996 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003997 return rec;
3998 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003999 rec.canceled = true;
4000 mIntentSenderRecords.remove(key);
4001 }
4002 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004003 return rec;
4004 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004005 rec = new PendingIntentRecord(this, key, callingUid);
4006 mIntentSenderRecords.put(key, rec.ref);
4007 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4008 if (activity.pendingResults == null) {
4009 activity.pendingResults
4010 = new HashSet<WeakReference<PendingIntentRecord>>();
4011 }
4012 activity.pendingResults.add(rec.ref);
4013 }
4014 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004015 }
4016
4017 public void cancelIntentSender(IIntentSender sender) {
4018 if (!(sender instanceof PendingIntentRecord)) {
4019 return;
4020 }
4021 synchronized(this) {
4022 PendingIntentRecord rec = (PendingIntentRecord)sender;
4023 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004024 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004025 .getPackageUid(rec.key.packageName);
4026 if (uid != Binder.getCallingUid()) {
4027 String msg = "Permission Denial: cancelIntentSender() from pid="
4028 + Binder.getCallingPid()
4029 + ", uid=" + Binder.getCallingUid()
4030 + " is not allowed to cancel packges "
4031 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004032 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004033 throw new SecurityException(msg);
4034 }
4035 } catch (RemoteException e) {
4036 throw new SecurityException(e);
4037 }
4038 cancelIntentSenderLocked(rec, true);
4039 }
4040 }
4041
4042 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4043 rec.canceled = true;
4044 mIntentSenderRecords.remove(rec.key);
4045 if (cleanActivity && rec.key.activity != null) {
4046 rec.key.activity.pendingResults.remove(rec.ref);
4047 }
4048 }
4049
4050 public String getPackageForIntentSender(IIntentSender pendingResult) {
4051 if (!(pendingResult instanceof PendingIntentRecord)) {
4052 return null;
4053 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004054 try {
4055 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4056 return res.key.packageName;
4057 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004058 }
4059 return null;
4060 }
4061
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004062 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4063 if (!(pendingResult instanceof PendingIntentRecord)) {
4064 return false;
4065 }
4066 try {
4067 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4068 if (res.key.allIntents == null) {
4069 return false;
4070 }
4071 for (int i=0; i<res.key.allIntents.length; i++) {
4072 Intent intent = res.key.allIntents[i];
4073 if (intent.getPackage() != null && intent.getComponent() != null) {
4074 return false;
4075 }
4076 }
4077 return true;
4078 } catch (ClassCastException e) {
4079 }
4080 return false;
4081 }
4082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004083 public void setProcessLimit(int max) {
4084 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4085 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004086 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004087 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004088 mProcessLimitOverride = max;
4089 }
4090 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 }
4092
4093 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004094 synchronized (this) {
4095 return mProcessLimitOverride;
4096 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 }
4098
4099 void foregroundTokenDied(ForegroundToken token) {
4100 synchronized (ActivityManagerService.this) {
4101 synchronized (mPidsSelfLocked) {
4102 ForegroundToken cur
4103 = mForegroundProcesses.get(token.pid);
4104 if (cur != token) {
4105 return;
4106 }
4107 mForegroundProcesses.remove(token.pid);
4108 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4109 if (pr == null) {
4110 return;
4111 }
4112 pr.forcingToForeground = null;
4113 pr.foregroundServices = false;
4114 }
4115 updateOomAdjLocked();
4116 }
4117 }
4118
4119 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4120 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4121 "setProcessForeground()");
4122 synchronized(this) {
4123 boolean changed = false;
4124
4125 synchronized (mPidsSelfLocked) {
4126 ProcessRecord pr = mPidsSelfLocked.get(pid);
4127 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004128 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004129 return;
4130 }
4131 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4132 if (oldToken != null) {
4133 oldToken.token.unlinkToDeath(oldToken, 0);
4134 mForegroundProcesses.remove(pid);
4135 pr.forcingToForeground = null;
4136 changed = true;
4137 }
4138 if (isForeground && token != null) {
4139 ForegroundToken newToken = new ForegroundToken() {
4140 public void binderDied() {
4141 foregroundTokenDied(this);
4142 }
4143 };
4144 newToken.pid = pid;
4145 newToken.token = token;
4146 try {
4147 token.linkToDeath(newToken, 0);
4148 mForegroundProcesses.put(pid, newToken);
4149 pr.forcingToForeground = token;
4150 changed = true;
4151 } catch (RemoteException e) {
4152 // If the process died while doing this, we will later
4153 // do the cleanup with the process death link.
4154 }
4155 }
4156 }
4157
4158 if (changed) {
4159 updateOomAdjLocked();
4160 }
4161 }
4162 }
4163
4164 // =========================================================
4165 // PERMISSIONS
4166 // =========================================================
4167
4168 static class PermissionController extends IPermissionController.Stub {
4169 ActivityManagerService mActivityManagerService;
4170 PermissionController(ActivityManagerService activityManagerService) {
4171 mActivityManagerService = activityManagerService;
4172 }
4173
4174 public boolean checkPermission(String permission, int pid, int uid) {
4175 return mActivityManagerService.checkPermission(permission, pid,
4176 uid) == PackageManager.PERMISSION_GRANTED;
4177 }
4178 }
4179
4180 /**
4181 * This can be called with or without the global lock held.
4182 */
4183 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004184 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004185 // We might be performing an operation on behalf of an indirect binder
4186 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4187 // client identity accordingly before proceeding.
4188 Identity tlsIdentity = sCallerIdentity.get();
4189 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004190 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4192 uid = tlsIdentity.uid;
4193 pid = tlsIdentity.pid;
4194 }
4195
4196 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004197 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004198 return PackageManager.PERMISSION_GRANTED;
4199 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004200 // If there is a uid that owns whatever is being accessed, it has
4201 // blanket access to it regardless of the permissions it requires.
4202 if (owningUid >= 0 && uid == owningUid) {
4203 return PackageManager.PERMISSION_GRANTED;
4204 }
4205 // If the target is not exported, then nobody else can get to it.
4206 if (!exported) {
4207 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004208 return PackageManager.PERMISSION_DENIED;
4209 }
4210 if (permission == null) {
4211 return PackageManager.PERMISSION_GRANTED;
4212 }
4213 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004214 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004215 .checkUidPermission(permission, uid);
4216 } catch (RemoteException e) {
4217 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004218 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004219 }
4220 return PackageManager.PERMISSION_DENIED;
4221 }
4222
4223 /**
4224 * As the only public entry point for permissions checking, this method
4225 * can enforce the semantic that requesting a check on a null global
4226 * permission is automatically denied. (Internally a null permission
4227 * string is used when calling {@link #checkComponentPermission} in cases
4228 * when only uid-based security is needed.)
4229 *
4230 * This can be called with or without the global lock held.
4231 */
4232 public int checkPermission(String permission, int pid, int uid) {
4233 if (permission == null) {
4234 return PackageManager.PERMISSION_DENIED;
4235 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004236 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004237 }
4238
4239 /**
4240 * Binder IPC calls go through the public entry point.
4241 * This can be called with or without the global lock held.
4242 */
4243 int checkCallingPermission(String permission) {
4244 return checkPermission(permission,
4245 Binder.getCallingPid(),
4246 Binder.getCallingUid());
4247 }
4248
4249 /**
4250 * This can be called with or without the global lock held.
4251 */
4252 void enforceCallingPermission(String permission, String func) {
4253 if (checkCallingPermission(permission)
4254 == PackageManager.PERMISSION_GRANTED) {
4255 return;
4256 }
4257
4258 String msg = "Permission Denial: " + func + " from pid="
4259 + Binder.getCallingPid()
4260 + ", uid=" + Binder.getCallingUid()
4261 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004262 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004263 throw new SecurityException(msg);
4264 }
4265
4266 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004267 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4268 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4269 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4270 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4271 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004272 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004273 // Is the component private from the target uid?
4274 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4275
4276 // Acceptable if the there is no read permission needed from the
4277 // target or the target is holding the read permission.
4278 if (!readPerm) {
4279 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004280 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004281 == PackageManager.PERMISSION_GRANTED)) {
4282 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004283 }
4284 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004285
4286 // Acceptable if the there is no write permission needed from the
4287 // target or the target is holding the read permission.
4288 if (!writePerm) {
4289 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004290 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004291 == PackageManager.PERMISSION_GRANTED)) {
4292 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 }
4294 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004295
4296 // Acceptable if there is a path permission matching the URI that
4297 // the target holds the permission on.
4298 PathPermission[] pps = pi.pathPermissions;
4299 if (pps != null && (!readPerm || !writePerm)) {
4300 final String path = uri.getPath();
4301 int i = pps.length;
4302 while (i > 0 && (!readPerm || !writePerm)) {
4303 i--;
4304 PathPermission pp = pps[i];
4305 if (!readPerm) {
4306 final String pprperm = pp.getReadPermission();
4307 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4308 + pprperm + " for " + pp.getPath()
4309 + ": match=" + pp.match(path)
4310 + " check=" + pm.checkUidPermission(pprperm, uid));
4311 if (pprperm != null && pp.match(path) &&
4312 (pm.checkUidPermission(pprperm, uid)
4313 == PackageManager.PERMISSION_GRANTED)) {
4314 readPerm = true;
4315 }
4316 }
4317 if (!writePerm) {
4318 final String ppwperm = pp.getWritePermission();
4319 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4320 + ppwperm + " for " + pp.getPath()
4321 + ": match=" + pp.match(path)
4322 + " check=" + pm.checkUidPermission(ppwperm, uid));
4323 if (ppwperm != null && pp.match(path) &&
4324 (pm.checkUidPermission(ppwperm, uid)
4325 == PackageManager.PERMISSION_GRANTED)) {
4326 writePerm = true;
4327 }
4328 }
4329 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004331 } catch (RemoteException e) {
4332 return false;
4333 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004334
4335 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004336 }
4337
4338 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4339 int modeFlags) {
4340 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004341 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004342 return true;
4343 }
4344 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4345 if (perms == null) return false;
4346 UriPermission perm = perms.get(uri);
4347 if (perm == null) return false;
4348 return (modeFlags&perm.modeFlags) == modeFlags;
4349 }
4350
4351 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4352 // Another redirected-binder-call permissions check as in
4353 // {@link checkComponentPermission}.
4354 Identity tlsIdentity = sCallerIdentity.get();
4355 if (tlsIdentity != null) {
4356 uid = tlsIdentity.uid;
4357 pid = tlsIdentity.pid;
4358 }
4359
4360 // Our own process gets to do everything.
4361 if (pid == MY_PID) {
4362 return PackageManager.PERMISSION_GRANTED;
4363 }
4364 synchronized(this) {
4365 return checkUriPermissionLocked(uri, uid, modeFlags)
4366 ? PackageManager.PERMISSION_GRANTED
4367 : PackageManager.PERMISSION_DENIED;
4368 }
4369 }
4370
Dianne Hackborn39792d22010-08-19 18:01:52 -07004371 /**
4372 * Check if the targetPkg can be granted permission to access uri by
4373 * the callingUid using the given modeFlags. Throws a security exception
4374 * if callingUid is not allowed to do this. Returns the uid of the target
4375 * if the URI permission grant should be performed; returns -1 if it is not
4376 * needed (for example targetPkg already has permission to access the URI).
4377 */
4378 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4379 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4381 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4382 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004383 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004384 }
4385
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004386 if (targetPkg != null) {
4387 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4388 "Checking grant " + targetPkg + " permission to " + uri);
4389 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004390
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004391 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004392
4393 // If this is not a content: uri, we can't do anything with it.
4394 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004395 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004396 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004397 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004398 }
4399
4400 String name = uri.getAuthority();
4401 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004402 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 if (cpr != null) {
4404 pi = cpr.info;
4405 } else {
4406 try {
4407 pi = pm.resolveContentProvider(name,
4408 PackageManager.GET_URI_PERMISSION_PATTERNS);
4409 } catch (RemoteException ex) {
4410 }
4411 }
4412 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004413 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004414 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004415 }
4416
4417 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004418 if (targetPkg != null) {
4419 try {
4420 targetUid = pm.getPackageUid(targetPkg);
4421 if (targetUid < 0) {
4422 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4423 "Can't grant URI permission no uid for: " + targetPkg);
4424 return -1;
4425 }
4426 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004427 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004428 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004429 } else {
4430 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004431 }
4432
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004433 if (targetUid >= 0) {
4434 // First... does the target actually need this permission?
4435 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4436 // No need to grant the target this permission.
4437 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4438 "Target " + targetPkg + " already has full permission to " + uri);
4439 return -1;
4440 }
4441 } else {
4442 // First... there is no target package, so can anyone access it?
4443 boolean allowed = pi.exported;
4444 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4445 if (pi.readPermission != null) {
4446 allowed = false;
4447 }
4448 }
4449 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4450 if (pi.writePermission != null) {
4451 allowed = false;
4452 }
4453 }
4454 if (allowed) {
4455 return -1;
4456 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004457 }
4458
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004459 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004460 if (!pi.grantUriPermissions) {
4461 throw new SecurityException("Provider " + pi.packageName
4462 + "/" + pi.name
4463 + " does not allow granting of Uri permissions (uri "
4464 + uri + ")");
4465 }
4466 if (pi.uriPermissionPatterns != null) {
4467 final int N = pi.uriPermissionPatterns.length;
4468 boolean allowed = false;
4469 for (int i=0; i<N; i++) {
4470 if (pi.uriPermissionPatterns[i] != null
4471 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4472 allowed = true;
4473 break;
4474 }
4475 }
4476 if (!allowed) {
4477 throw new SecurityException("Provider " + pi.packageName
4478 + "/" + pi.name
4479 + " does not allow granting of permission to path of Uri "
4480 + uri);
4481 }
4482 }
4483
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004484 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004485 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004486 if (callingUid != Process.myUid()) {
4487 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4488 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4489 throw new SecurityException("Uid " + callingUid
4490 + " does not have permission to uri " + uri);
4491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004492 }
4493 }
4494
Dianne Hackborn39792d22010-08-19 18:01:52 -07004495 return targetUid;
4496 }
4497
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004498 public int checkGrantUriPermission(int callingUid, String targetPkg,
4499 Uri uri, int modeFlags) {
4500 synchronized(this) {
4501 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4502 }
4503 }
4504
Dianne Hackborn39792d22010-08-19 18:01:52 -07004505 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4506 Uri uri, int modeFlags, UriPermissionOwner owner) {
4507 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4508 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4509 if (modeFlags == 0) {
4510 return;
4511 }
4512
4513 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 // to the uri, and the target doesn't. Let's now give this to
4515 // the target.
4516
Joe Onorato8a9b2202010-02-26 18:56:32 -08004517 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004518 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004519
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004520 HashMap<Uri, UriPermission> targetUris
4521 = mGrantedUriPermissions.get(targetUid);
4522 if (targetUris == null) {
4523 targetUris = new HashMap<Uri, UriPermission>();
4524 mGrantedUriPermissions.put(targetUid, targetUris);
4525 }
4526
4527 UriPermission perm = targetUris.get(uri);
4528 if (perm == null) {
4529 perm = new UriPermission(targetUid, uri);
4530 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004531 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004533 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004534 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004535 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004536 } else {
4537 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4538 perm.readOwners.add(owner);
4539 owner.addReadPermission(perm);
4540 }
4541 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4542 perm.writeOwners.add(owner);
4543 owner.addWritePermission(perm);
4544 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004545 }
4546 }
4547
Dianne Hackborn39792d22010-08-19 18:01:52 -07004548 void grantUriPermissionLocked(int callingUid,
4549 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004550 if (targetPkg == null) {
4551 throw new NullPointerException("targetPkg");
4552 }
4553
Dianne Hackborn39792d22010-08-19 18:01:52 -07004554 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4555 if (targetUid < 0) {
4556 return;
4557 }
4558
4559 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4560 }
4561
4562 /**
4563 * Like checkGrantUriPermissionLocked, but takes an Intent.
4564 */
4565 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4566 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004567 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004568 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004569 + " from " + intent + "; flags=0x"
4570 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4571
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004572 if (targetPkg == null) {
4573 throw new NullPointerException("targetPkg");
4574 }
4575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004576 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004577 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004578 }
4579 Uri data = intent.getData();
4580 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004581 return -1;
4582 }
4583 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4584 intent.getFlags());
4585 }
4586
4587 /**
4588 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4589 */
4590 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4591 String targetPkg, Intent intent, UriPermissionOwner owner) {
4592 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4593 intent.getFlags(), owner);
4594 }
4595
4596 void grantUriPermissionFromIntentLocked(int callingUid,
4597 String targetPkg, Intent intent, UriPermissionOwner owner) {
4598 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4599 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 return;
4601 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004602
4603 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004604 }
4605
4606 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4607 Uri uri, int modeFlags) {
4608 synchronized(this) {
4609 final ProcessRecord r = getRecordForAppLocked(caller);
4610 if (r == null) {
4611 throw new SecurityException("Unable to find app for caller "
4612 + caller
4613 + " when granting permission to uri " + uri);
4614 }
4615 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004616 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004617 }
4618 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004619 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004620 }
4621
4622 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4623 null);
4624 }
4625 }
4626
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004627 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004628 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4629 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4630 HashMap<Uri, UriPermission> perms
4631 = mGrantedUriPermissions.get(perm.uid);
4632 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004633 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004634 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004635 perms.remove(perm.uri);
4636 if (perms.size() == 0) {
4637 mGrantedUriPermissions.remove(perm.uid);
4638 }
4639 }
4640 }
4641 }
4642
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004643 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4644 int modeFlags) {
4645 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4646 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4647 if (modeFlags == 0) {
4648 return;
4649 }
4650
Joe Onorato8a9b2202010-02-26 18:56:32 -08004651 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004652 "Revoking all granted permissions to " + uri);
4653
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004654 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004655
4656 final String authority = uri.getAuthority();
4657 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004658 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004659 if (cpr != null) {
4660 pi = cpr.info;
4661 } else {
4662 try {
4663 pi = pm.resolveContentProvider(authority,
4664 PackageManager.GET_URI_PERMISSION_PATTERNS);
4665 } catch (RemoteException ex) {
4666 }
4667 }
4668 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004669 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004670 return;
4671 }
4672
4673 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004674 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004675 // Right now, if you are not the original owner of the permission,
4676 // you are not allowed to revoke it.
4677 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4678 throw new SecurityException("Uid " + callingUid
4679 + " does not have permission to uri " + uri);
4680 //}
4681 }
4682
4683 // Go through all of the permissions and remove any that match.
4684 final List<String> SEGMENTS = uri.getPathSegments();
4685 if (SEGMENTS != null) {
4686 final int NS = SEGMENTS.size();
4687 int N = mGrantedUriPermissions.size();
4688 for (int i=0; i<N; i++) {
4689 HashMap<Uri, UriPermission> perms
4690 = mGrantedUriPermissions.valueAt(i);
4691 Iterator<UriPermission> it = perms.values().iterator();
4692 toploop:
4693 while (it.hasNext()) {
4694 UriPermission perm = it.next();
4695 Uri targetUri = perm.uri;
4696 if (!authority.equals(targetUri.getAuthority())) {
4697 continue;
4698 }
4699 List<String> targetSegments = targetUri.getPathSegments();
4700 if (targetSegments == null) {
4701 continue;
4702 }
4703 if (targetSegments.size() < NS) {
4704 continue;
4705 }
4706 for (int j=0; j<NS; j++) {
4707 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4708 continue toploop;
4709 }
4710 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004711 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004712 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004713 perm.clearModes(modeFlags);
4714 if (perm.modeFlags == 0) {
4715 it.remove();
4716 }
4717 }
4718 if (perms.size() == 0) {
4719 mGrantedUriPermissions.remove(
4720 mGrantedUriPermissions.keyAt(i));
4721 N--;
4722 i--;
4723 }
4724 }
4725 }
4726 }
4727
4728 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4729 int modeFlags) {
4730 synchronized(this) {
4731 final ProcessRecord r = getRecordForAppLocked(caller);
4732 if (r == null) {
4733 throw new SecurityException("Unable to find app for caller "
4734 + caller
4735 + " when revoking permission to uri " + uri);
4736 }
4737 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004738 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004739 return;
4740 }
4741
4742 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4743 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4744 if (modeFlags == 0) {
4745 return;
4746 }
4747
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004748 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004749
4750 final String authority = uri.getAuthority();
4751 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004752 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004753 if (cpr != null) {
4754 pi = cpr.info;
4755 } else {
4756 try {
4757 pi = pm.resolveContentProvider(authority,
4758 PackageManager.GET_URI_PERMISSION_PATTERNS);
4759 } catch (RemoteException ex) {
4760 }
4761 }
4762 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004763 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004764 return;
4765 }
4766
4767 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4768 }
4769 }
4770
Dianne Hackborn7e269642010-08-25 19:50:20 -07004771 @Override
4772 public IBinder newUriPermissionOwner(String name) {
4773 synchronized(this) {
4774 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4775 return owner.getExternalTokenLocked();
4776 }
4777 }
4778
4779 @Override
4780 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4781 Uri uri, int modeFlags) {
4782 synchronized(this) {
4783 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4784 if (owner == null) {
4785 throw new IllegalArgumentException("Unknown owner: " + token);
4786 }
4787 if (fromUid != Binder.getCallingUid()) {
4788 if (Binder.getCallingUid() != Process.myUid()) {
4789 // Only system code can grant URI permissions on behalf
4790 // of other users.
4791 throw new SecurityException("nice try");
4792 }
4793 }
4794 if (targetPkg == null) {
4795 throw new IllegalArgumentException("null target");
4796 }
4797 if (uri == null) {
4798 throw new IllegalArgumentException("null uri");
4799 }
4800
4801 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4802 }
4803 }
4804
4805 @Override
4806 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4807 synchronized(this) {
4808 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4809 if (owner == null) {
4810 throw new IllegalArgumentException("Unknown owner: " + token);
4811 }
4812
4813 if (uri == null) {
4814 owner.removeUriPermissionsLocked(mode);
4815 } else {
4816 owner.removeUriPermissionLocked(uri, mode);
4817 }
4818 }
4819 }
4820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004821 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4822 synchronized (this) {
4823 ProcessRecord app =
4824 who != null ? getRecordForAppLocked(who) : null;
4825 if (app == null) return;
4826
4827 Message msg = Message.obtain();
4828 msg.what = WAIT_FOR_DEBUGGER_MSG;
4829 msg.obj = app;
4830 msg.arg1 = waiting ? 1 : 0;
4831 mHandler.sendMessage(msg);
4832 }
4833 }
4834
4835 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004836 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4837 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004838 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004839 outInfo.threshold = homeAppMem;
4840 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4841 outInfo.hiddenAppThreshold = hiddenAppMem;
4842 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4843 ProcessList.SECONDARY_SERVER_ADJ);
4844 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4845 ProcessList.VISIBLE_APP_ADJ);
4846 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4847 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004848 }
4849
4850 // =========================================================
4851 // TASK MANAGEMENT
4852 // =========================================================
4853
4854 public List getTasks(int maxNum, int flags,
4855 IThumbnailReceiver receiver) {
4856 ArrayList list = new ArrayList();
4857
4858 PendingThumbnailsRecord pending = null;
4859 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004860 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004861
4862 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004863 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004864 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4865 + ", receiver=" + receiver);
4866
4867 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4868 != PackageManager.PERMISSION_GRANTED) {
4869 if (receiver != null) {
4870 // If the caller wants to wait for pending thumbnails,
4871 // it ain't gonna get them.
4872 try {
4873 receiver.finished();
4874 } catch (RemoteException ex) {
4875 }
4876 }
4877 String msg = "Permission Denial: getTasks() from pid="
4878 + Binder.getCallingPid()
4879 + ", uid=" + Binder.getCallingUid()
4880 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004881 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004882 throw new SecurityException(msg);
4883 }
4884
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004885 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004886 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004887 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004888 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004889 TaskRecord curTask = null;
4890 int numActivities = 0;
4891 int numRunning = 0;
4892 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004893 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004894 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004895 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004896
4897 // Initialize state for next task if needed.
4898 if (top == null ||
4899 (top.state == ActivityState.INITIALIZING
4900 && top.task == r.task)) {
4901 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004902 curTask = r.task;
4903 numActivities = numRunning = 0;
4904 }
4905
4906 // Add 'r' into the current task.
4907 numActivities++;
4908 if (r.app != null && r.app.thread != null) {
4909 numRunning++;
4910 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004911
Joe Onorato8a9b2202010-02-26 18:56:32 -08004912 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004913 TAG, r.intent.getComponent().flattenToShortString()
4914 + ": task=" + r.task);
4915
4916 // If the next one is a different task, generate a new
4917 // TaskInfo entry for what we have.
4918 if (next == null || next.task != curTask) {
4919 ActivityManager.RunningTaskInfo ci
4920 = new ActivityManager.RunningTaskInfo();
4921 ci.id = curTask.taskId;
4922 ci.baseActivity = r.intent.getComponent();
4923 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004924 if (top.thumbHolder != null) {
4925 ci.description = top.thumbHolder.lastDescription;
4926 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004927 ci.numActivities = numActivities;
4928 ci.numRunning = numRunning;
4929 //System.out.println(
4930 // "#" + maxNum + ": " + " descr=" + ci.description);
4931 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004932 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 TAG, "State=" + top.state + "Idle=" + top.idle
4934 + " app=" + top.app
4935 + " thr=" + (top.app != null ? top.app.thread : null));
4936 if (top.state == ActivityState.RESUMED
4937 || top.state == ActivityState.PAUSING) {
4938 if (top.idle && top.app != null
4939 && top.app.thread != null) {
4940 topRecord = top;
4941 topThumbnail = top.app.thread;
4942 } else {
4943 top.thumbnailNeeded = true;
4944 }
4945 }
4946 if (pending == null) {
4947 pending = new PendingThumbnailsRecord(receiver);
4948 }
4949 pending.pendingRecords.add(top);
4950 }
4951 list.add(ci);
4952 maxNum--;
4953 top = null;
4954 }
4955 }
4956
4957 if (pending != null) {
4958 mPendingThumbnails.add(pending);
4959 }
4960 }
4961
Joe Onorato8a9b2202010-02-26 18:56:32 -08004962 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004963
4964 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004965 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004966 try {
4967 topThumbnail.requestThumbnail(topRecord);
4968 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004969 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004970 sendPendingThumbnail(null, topRecord, null, null, true);
4971 }
4972 }
4973
4974 if (pending == null && receiver != null) {
4975 // In this case all thumbnails were available and the client
4976 // is being asked to be told when the remaining ones come in...
4977 // which is unusually, since the top-most currently running
4978 // activity should never have a canned thumbnail! Oh well.
4979 try {
4980 receiver.finished();
4981 } catch (RemoteException ex) {
4982 }
4983 }
4984
4985 return list;
4986 }
4987
4988 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4989 int flags) {
4990 synchronized (this) {
4991 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4992 "getRecentTasks()");
4993
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004994 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07004995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004996 final int N = mRecentTasks.size();
4997 ArrayList<ActivityManager.RecentTaskInfo> res
4998 = new ArrayList<ActivityManager.RecentTaskInfo>(
4999 maxNum < N ? maxNum : N);
5000 for (int i=0; i<N && maxNum > 0; i++) {
5001 TaskRecord tr = mRecentTasks.get(i);
5002 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5003 || (tr.intent == null)
5004 || ((tr.intent.getFlags()
5005 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5006 ActivityManager.RecentTaskInfo rti
5007 = new ActivityManager.RecentTaskInfo();
5008 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005009 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005010 rti.baseIntent = new Intent(
5011 tr.intent != null ? tr.intent : tr.affinityIntent);
5012 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005013 rti.description = tr.lastDescription;
5014
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005015 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5016 // Check whether this activity is currently available.
5017 try {
5018 if (rti.origActivity != null) {
5019 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5020 continue;
5021 }
5022 } else if (rti.baseIntent != null) {
5023 if (pm.queryIntentActivities(rti.baseIntent,
5024 null, 0) == null) {
5025 continue;
5026 }
5027 }
5028 } catch (RemoteException e) {
5029 // Will never happen.
5030 }
5031 }
5032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005033 res.add(rti);
5034 maxNum--;
5035 }
5036 }
5037 return res;
5038 }
5039 }
5040
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005041 private TaskRecord taskForIdLocked(int id) {
5042 final int N = mRecentTasks.size();
5043 for (int i=0; i<N; i++) {
5044 TaskRecord tr = mRecentTasks.get(i);
5045 if (tr.taskId == id) {
5046 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005047 }
5048 }
5049 return null;
5050 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005051
5052 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5053 synchronized (this) {
5054 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5055 "getTaskThumbnails()");
5056 TaskRecord tr = taskForIdLocked(id);
5057 if (tr != null) {
5058 return mMainStack.getTaskThumbnailsLocked(tr);
5059 }
5060 }
5061 return null;
5062 }
5063
5064 public boolean removeSubTask(int taskId, int subTaskIndex) {
5065 synchronized (this) {
5066 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5067 "removeSubTask()");
5068 long ident = Binder.clearCallingIdentity();
5069 try {
5070 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5071 } finally {
5072 Binder.restoreCallingIdentity(ident);
5073 }
5074 }
5075 }
5076
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005077 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005078 TaskRecord tr = root.task;
5079 Intent baseIntent = new Intent(
5080 tr.intent != null ? tr.intent : tr.affinityIntent);
5081 ComponentName component = baseIntent.getComponent();
5082 if (component == null) {
5083 Slog.w(TAG, "Now component for base intent of task: " + tr);
5084 return;
5085 }
5086
5087 // Find any running services associated with this app.
5088 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5089 for (ServiceRecord sr : mServices.values()) {
5090 if (sr.packageName.equals(component.getPackageName())) {
5091 services.add(sr);
5092 }
5093 }
5094
5095 // Take care of any running services associated with the app.
5096 for (int i=0; i<services.size(); i++) {
5097 ServiceRecord sr = services.get(i);
5098 if (sr.startRequested) {
5099 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005100 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005101 stopServiceLocked(sr);
5102 } else {
5103 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5104 sr.makeNextStartId(), baseIntent, -1));
5105 if (sr.app != null && sr.app.thread != null) {
5106 sendServiceArgsLocked(sr, false);
5107 }
5108 }
5109 }
5110 }
5111
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005112 if (killProcesses) {
5113 // Find any running processes associated with this app.
5114 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5115 SparseArray<ProcessRecord> appProcs
5116 = mProcessNames.getMap().get(component.getPackageName());
5117 if (appProcs != null) {
5118 for (int i=0; i<appProcs.size(); i++) {
5119 procs.add(appProcs.valueAt(i));
5120 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005121 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005122
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005123 // Kill the running processes.
5124 for (int i=0; i<procs.size(); i++) {
5125 ProcessRecord pr = procs.get(i);
5126 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5127 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5128 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5129 pr.processName, pr.setAdj, "remove task");
5130 Process.killProcessQuiet(pr.pid);
5131 } else {
5132 pr.waitingToKill = "remove task";
5133 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005134 }
5135 }
5136 }
5137
5138 public boolean removeTask(int taskId, int flags) {
5139 synchronized (this) {
5140 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5141 "removeTask()");
5142 long ident = Binder.clearCallingIdentity();
5143 try {
5144 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5145 if (r != null) {
5146 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005147 cleanUpRemovedTaskLocked(r,
5148 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005149 return true;
5150 }
5151 } finally {
5152 Binder.restoreCallingIdentity(ident);
5153 }
5154 }
5155 return false;
5156 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005157
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005158 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5159 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005160 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005161 TaskRecord jt = startTask;
5162
5163 // First look backwards
5164 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005165 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005166 if (r.task != jt) {
5167 jt = r.task;
5168 if (affinity.equals(jt.affinity)) {
5169 return j;
5170 }
5171 }
5172 }
5173
5174 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005175 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005176 jt = startTask;
5177 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005178 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005179 if (r.task != jt) {
5180 if (affinity.equals(jt.affinity)) {
5181 return j;
5182 }
5183 jt = r.task;
5184 }
5185 }
5186
5187 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005188 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005189 return N-1;
5190 }
5191
5192 return -1;
5193 }
5194
5195 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005196 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005197 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005198 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005199 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5200 "moveTaskToFront()");
5201
5202 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005203 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5204 Binder.getCallingUid(), "Task to front")) {
5205 return;
5206 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005207 final long origId = Binder.clearCallingIdentity();
5208 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005209 TaskRecord tr = taskForIdLocked(task);
5210 if (tr != null) {
5211 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5212 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005214 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5215 // Caller wants the home activity moved with it. To accomplish this,
5216 // we'll just move the home task to the top first.
5217 mMainStack.moveHomeToFrontLocked();
5218 }
5219 mMainStack.moveTaskToFrontLocked(tr, null);
5220 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005221 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005222 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5223 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005224 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005225 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5226 mMainStack.mUserLeaving = true;
5227 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005228 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5229 // Caller wants the home activity moved with it. To accomplish this,
5230 // we'll just move the home task to the top first.
5231 mMainStack.moveHomeToFrontLocked();
5232 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005233 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005234 return;
5235 }
5236 }
5237 } finally {
5238 Binder.restoreCallingIdentity(origId);
5239 }
5240 }
5241 }
5242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005243 public void moveTaskToBack(int task) {
5244 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5245 "moveTaskToBack()");
5246
5247 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005248 if (mMainStack.mResumedActivity != null
5249 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005250 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5251 Binder.getCallingUid(), "Task to back")) {
5252 return;
5253 }
5254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005255 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005256 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005257 Binder.restoreCallingIdentity(origId);
5258 }
5259 }
5260
5261 /**
5262 * Moves an activity, and all of the other activities within the same task, to the bottom
5263 * of the history stack. The activity's order within the task is unchanged.
5264 *
5265 * @param token A reference to the activity we wish to move
5266 * @param nonRoot If false then this only works if the activity is the root
5267 * of a task; if true it will work for any activity in a task.
5268 * @return Returns true if the move completed, false if not.
5269 */
5270 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5271 synchronized(this) {
5272 final long origId = Binder.clearCallingIdentity();
5273 int taskId = getTaskForActivityLocked(token, !nonRoot);
5274 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005275 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005276 }
5277 Binder.restoreCallingIdentity(origId);
5278 }
5279 return false;
5280 }
5281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005282 public void moveTaskBackwards(int task) {
5283 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5284 "moveTaskBackwards()");
5285
5286 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005287 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5288 Binder.getCallingUid(), "Task backwards")) {
5289 return;
5290 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005291 final long origId = Binder.clearCallingIdentity();
5292 moveTaskBackwardsLocked(task);
5293 Binder.restoreCallingIdentity(origId);
5294 }
5295 }
5296
5297 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005298 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005299 }
5300
5301 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5302 synchronized(this) {
5303 return getTaskForActivityLocked(token, onlyRoot);
5304 }
5305 }
5306
5307 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005308 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005309 TaskRecord lastTask = null;
5310 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005311 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005312 if (r == token) {
5313 if (!onlyRoot || lastTask != r.task) {
5314 return r.task.taskId;
5315 }
5316 return -1;
5317 }
5318 lastTask = r.task;
5319 }
5320
5321 return -1;
5322 }
5323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005324 public void finishOtherInstances(IBinder token, ComponentName className) {
5325 synchronized(this) {
5326 final long origId = Binder.clearCallingIdentity();
5327
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005328 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005329 TaskRecord lastTask = null;
5330 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005331 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005332 if (r.realActivity.equals(className)
5333 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005334 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005335 null, "others")) {
5336 i--;
5337 N--;
5338 }
5339 }
5340 lastTask = r.task;
5341 }
5342
5343 Binder.restoreCallingIdentity(origId);
5344 }
5345 }
5346
5347 // =========================================================
5348 // THUMBNAILS
5349 // =========================================================
5350
5351 public void reportThumbnail(IBinder token,
5352 Bitmap thumbnail, CharSequence description) {
5353 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5354 final long origId = Binder.clearCallingIdentity();
5355 sendPendingThumbnail(null, token, thumbnail, description, true);
5356 Binder.restoreCallingIdentity(origId);
5357 }
5358
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005359 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005360 Bitmap thumbnail, CharSequence description, boolean always) {
5361 TaskRecord task = null;
5362 ArrayList receivers = null;
5363
5364 //System.out.println("Send pending thumbnail: " + r);
5365
5366 synchronized(this) {
5367 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005368 r = mMainStack.isInStackLocked(token);
5369 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005370 return;
5371 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005372 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005373 if (thumbnail == null && r.thumbHolder != null) {
5374 thumbnail = r.thumbHolder.lastThumbnail;
5375 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005376 }
5377 if (thumbnail == null && !always) {
5378 // If there is no thumbnail, and this entry is not actually
5379 // going away, then abort for now and pick up the next
5380 // thumbnail we get.
5381 return;
5382 }
5383 task = r.task;
5384
5385 int N = mPendingThumbnails.size();
5386 int i=0;
5387 while (i<N) {
5388 PendingThumbnailsRecord pr =
5389 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5390 //System.out.println("Looking in " + pr.pendingRecords);
5391 if (pr.pendingRecords.remove(r)) {
5392 if (receivers == null) {
5393 receivers = new ArrayList();
5394 }
5395 receivers.add(pr);
5396 if (pr.pendingRecords.size() == 0) {
5397 pr.finished = true;
5398 mPendingThumbnails.remove(i);
5399 N--;
5400 continue;
5401 }
5402 }
5403 i++;
5404 }
5405 }
5406
5407 if (receivers != null) {
5408 final int N = receivers.size();
5409 for (int i=0; i<N; i++) {
5410 try {
5411 PendingThumbnailsRecord pr =
5412 (PendingThumbnailsRecord)receivers.get(i);
5413 pr.receiver.newThumbnail(
5414 task != null ? task.taskId : -1, thumbnail, description);
5415 if (pr.finished) {
5416 pr.receiver.finished();
5417 }
5418 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005419 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005420 }
5421 }
5422 }
5423 }
5424
5425 // =========================================================
5426 // CONTENT PROVIDERS
5427 // =========================================================
5428
Jeff Brown10e89712011-07-08 18:52:57 -07005429 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5430 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005431 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005432 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005433 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005434 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005435 } catch (RemoteException ex) {
5436 }
5437 if (providers != null) {
5438 final int N = providers.size();
5439 for (int i=0; i<N; i++) {
5440 ProviderInfo cpi =
5441 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005442 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005443 if (cpr == null) {
5444 cpr = new ContentProviderRecord(cpi, app.info);
5445 mProvidersByClass.put(cpi.name, cpr);
5446 }
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 }
5610
Dianne Hackborn860755f2010-06-03 18:47:52 -07005611 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005612 final boolean firstClass = cpr == null;
5613 if (firstClass) {
5614 try {
5615 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005616 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005617 getApplicationInfo(
5618 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005619 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005620 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005621 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005622 + cpi.name);
5623 return null;
5624 }
5625 cpr = new ContentProviderRecord(cpi, ai);
5626 } catch (RemoteException ex) {
5627 // pm is in same process, this will never happen.
5628 }
5629 }
5630
5631 if (r != null && cpr.canRunHere(r)) {
5632 // If this is a multiprocess provider, then just return its
5633 // info and allow the caller to instantiate it. Only do
5634 // this if the provider is the same user as the caller's
5635 // process, or can run as root (so can be in any process).
5636 return cpr;
5637 }
5638
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005639 if (DEBUG_PROVIDER) {
5640 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005641 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005642 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005643 }
5644
5645 // This is single process, and our app is now connecting to it.
5646 // See if we are already in the process of launching this
5647 // provider.
5648 final int N = mLaunchingProviders.size();
5649 int i;
5650 for (i=0; i<N; i++) {
5651 if (mLaunchingProviders.get(i) == cpr) {
5652 break;
5653 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005654 }
5655
5656 // If the provider is not already being launched, then get it
5657 // started.
5658 if (i >= N) {
5659 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005660
5661 try {
5662 // Content provider is now in use, its package can't be stopped.
5663 try {
5664 AppGlobals.getPackageManager().setPackageStoppedState(
5665 cpr.appInfo.packageName, false);
5666 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005667 } catch (IllegalArgumentException e) {
5668 Slog.w(TAG, "Failed trying to unstop package "
5669 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005670 }
5671
5672 ProcessRecord proc = startProcessLocked(cpi.processName,
5673 cpr.appInfo, false, 0, "content provider",
5674 new ComponentName(cpi.applicationInfo.packageName,
5675 cpi.name), false);
5676 if (proc == null) {
5677 Slog.w(TAG, "Unable to launch app "
5678 + cpi.applicationInfo.packageName + "/"
5679 + cpi.applicationInfo.uid + " for provider "
5680 + name + ": process is bad");
5681 return null;
5682 }
5683 cpr.launchingApp = proc;
5684 mLaunchingProviders.add(cpr);
5685 } finally {
5686 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005687 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005688 }
5689
5690 // Make sure the provider is published (the same provider class
5691 // may be published under multiple names).
5692 if (firstClass) {
5693 mProvidersByClass.put(cpi.name, cpr);
5694 }
5695 mProvidersByName.put(name, cpr);
5696
5697 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005698 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005699 "Adding provider requested by "
5700 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005701 + cpr.info.processName);
5702 Integer cnt = r.conProviders.get(cpr);
5703 if (cnt == null) {
5704 r.conProviders.put(cpr, new Integer(1));
5705 } else {
5706 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5707 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005708 cpr.clients.add(r);
5709 } else {
5710 cpr.externals++;
5711 }
5712 }
5713 }
5714
5715 // Wait for the provider to be published...
5716 synchronized (cpr) {
5717 while (cpr.provider == null) {
5718 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005719 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005720 + cpi.applicationInfo.packageName + "/"
5721 + cpi.applicationInfo.uid + " for provider "
5722 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005723 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005724 cpi.applicationInfo.packageName,
5725 cpi.applicationInfo.uid, name);
5726 return null;
5727 }
5728 try {
5729 cpr.wait();
5730 } catch (InterruptedException ex) {
5731 }
5732 }
5733 }
5734 return cpr;
5735 }
5736
5737 public final ContentProviderHolder getContentProvider(
5738 IApplicationThread caller, String name) {
5739 if (caller == null) {
5740 String msg = "null IApplicationThread when getting content provider "
5741 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005742 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005743 throw new SecurityException(msg);
5744 }
5745
5746 return getContentProviderImpl(caller, name);
5747 }
5748
5749 private ContentProviderHolder getContentProviderExternal(String name) {
5750 return getContentProviderImpl(null, name);
5751 }
5752
5753 /**
5754 * Drop a content provider from a ProcessRecord's bookkeeping
5755 * @param cpr
5756 */
5757 public void removeContentProvider(IApplicationThread caller, String name) {
5758 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005759 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005760 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005761 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005762 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005763 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005764 return;
5765 }
5766 final ProcessRecord r = getRecordForAppLocked(caller);
5767 if (r == null) {
5768 throw new SecurityException(
5769 "Unable to find app for caller " + caller +
5770 " when removing content provider " + name);
5771 }
5772 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005773 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005774 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005775 + r.info.processName + " from process "
5776 + localCpr.appInfo.processName);
5777 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005778 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005779 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005780 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005781 return;
5782 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005783 Integer cnt = r.conProviders.get(localCpr);
5784 if (cnt == null || cnt.intValue() <= 1) {
5785 localCpr.clients.remove(r);
5786 r.conProviders.remove(localCpr);
5787 } else {
5788 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790 }
5791 updateOomAdjLocked();
5792 }
5793 }
5794
5795 private void removeContentProviderExternal(String name) {
5796 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005797 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005798 if(cpr == null) {
5799 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005800 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005801 return;
5802 }
5803
5804 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005805 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005806 localCpr.externals--;
5807 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005808 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005809 }
5810 updateOomAdjLocked();
5811 }
5812 }
5813
5814 public final void publishContentProviders(IApplicationThread caller,
5815 List<ContentProviderHolder> providers) {
5816 if (providers == null) {
5817 return;
5818 }
5819
5820 synchronized(this) {
5821 final ProcessRecord r = getRecordForAppLocked(caller);
5822 if (r == null) {
5823 throw new SecurityException(
5824 "Unable to find app for caller " + caller
5825 + " (pid=" + Binder.getCallingPid()
5826 + ") when publishing content providers");
5827 }
5828
5829 final long origId = Binder.clearCallingIdentity();
5830
5831 final int N = providers.size();
5832 for (int i=0; i<N; i++) {
5833 ContentProviderHolder src = providers.get(i);
5834 if (src == null || src.info == null || src.provider == null) {
5835 continue;
5836 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005837 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005838 if (dst != null) {
5839 mProvidersByClass.put(dst.info.name, dst);
5840 String names[] = dst.info.authority.split(";");
5841 for (int j = 0; j < names.length; j++) {
5842 mProvidersByName.put(names[j], dst);
5843 }
5844
5845 int NL = mLaunchingProviders.size();
5846 int j;
5847 for (j=0; j<NL; j++) {
5848 if (mLaunchingProviders.get(j) == dst) {
5849 mLaunchingProviders.remove(j);
5850 j--;
5851 NL--;
5852 }
5853 }
5854 synchronized (dst) {
5855 dst.provider = src.provider;
5856 dst.app = r;
5857 dst.notifyAll();
5858 }
5859 updateOomAdjLocked(r);
5860 }
5861 }
5862
5863 Binder.restoreCallingIdentity(origId);
5864 }
5865 }
5866
5867 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07005868 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005869 synchronized (mSelf) {
5870 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5871 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005872 if (providers != null) {
5873 for (int i=providers.size()-1; i>=0; i--) {
5874 ProviderInfo pi = (ProviderInfo)providers.get(i);
5875 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5876 Slog.w(TAG, "Not installing system proc provider " + pi.name
5877 + ": not system .apk");
5878 providers.remove(i);
5879 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005880 }
5881 }
5882 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005883 if (providers != null) {
5884 mSystemThread.installSystemProviders(providers);
5885 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005886
5887 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01005888
5889 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005890 }
5891
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005892 /**
5893 * Allows app to retrieve the MIME type of a URI without having permission
5894 * to access its content provider.
5895 *
5896 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5897 *
5898 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5899 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5900 */
5901 public String getProviderMimeType(Uri uri) {
5902 final String name = uri.getAuthority();
5903 final long ident = Binder.clearCallingIdentity();
5904 ContentProviderHolder holder = null;
5905
5906 try {
5907 holder = getContentProviderExternal(name);
5908 if (holder != null) {
5909 return holder.provider.getType(uri);
5910 }
5911 } catch (RemoteException e) {
5912 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5913 return null;
5914 } finally {
5915 if (holder != null) {
5916 removeContentProviderExternal(name);
5917 }
5918 Binder.restoreCallingIdentity(ident);
5919 }
5920
5921 return null;
5922 }
5923
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005924 // =========================================================
5925 // GLOBAL MANAGEMENT
5926 // =========================================================
5927
5928 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5929 ApplicationInfo info, String customProcess) {
5930 String proc = customProcess != null ? customProcess : info.processName;
5931 BatteryStatsImpl.Uid.Proc ps = null;
5932 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5933 synchronized (stats) {
5934 ps = stats.getProcessStatsLocked(info.uid, proc);
5935 }
5936 return new ProcessRecord(ps, thread, info, proc);
5937 }
5938
5939 final ProcessRecord addAppLocked(ApplicationInfo info) {
5940 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5941
5942 if (app == null) {
5943 app = newProcessRecordLocked(null, info, null);
5944 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005945 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005946 }
5947
Dianne Hackborne7f97212011-02-24 14:40:20 -08005948 // This package really, really can not be stopped.
5949 try {
5950 AppGlobals.getPackageManager().setPackageStoppedState(
5951 info.packageName, false);
5952 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005953 } catch (IllegalArgumentException e) {
5954 Slog.w(TAG, "Failed trying to unstop package "
5955 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005956 }
5957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005958 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5959 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5960 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07005961 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005962 }
5963 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5964 mPersistentStartingProcesses.add(app);
5965 startProcessLocked(app, "added application", app.processName);
5966 }
5967
5968 return app;
5969 }
5970
5971 public void unhandledBack() {
5972 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5973 "unhandledBack()");
5974
5975 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005976 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005977 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005978 TAG, "Performing unhandledBack(): stack size = " + count);
5979 if (count > 1) {
5980 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005981 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005982 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5983 Binder.restoreCallingIdentity(origId);
5984 }
5985 }
5986 }
5987
5988 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5989 String name = uri.getAuthority();
5990 ContentProviderHolder cph = getContentProviderExternal(name);
5991 ParcelFileDescriptor pfd = null;
5992 if (cph != null) {
5993 // We record the binder invoker's uid in thread-local storage before
5994 // going to the content provider to open the file. Later, in the code
5995 // that handles all permissions checks, we look for this uid and use
5996 // that rather than the Activity Manager's own uid. The effect is that
5997 // we do the check against the caller's permissions even though it looks
5998 // to the content provider like the Activity Manager itself is making
5999 // the request.
6000 sCallerIdentity.set(new Identity(
6001 Binder.getCallingPid(), Binder.getCallingUid()));
6002 try {
6003 pfd = cph.provider.openFile(uri, "r");
6004 } catch (FileNotFoundException e) {
6005 // do nothing; pfd will be returned null
6006 } finally {
6007 // Ensure that whatever happens, we clean up the identity state
6008 sCallerIdentity.remove();
6009 }
6010
6011 // We've got the fd now, so we're done with the provider.
6012 removeContentProviderExternal(name);
6013 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006014 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006015 }
6016 return pfd;
6017 }
6018
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006019 // Actually is sleeping or shutting down or whatever else in the future
6020 // is an inactive state.
6021 public boolean isSleeping() {
6022 return mSleeping || mShuttingDown;
6023 }
6024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006025 public void goingToSleep() {
6026 synchronized(this) {
6027 mSleeping = true;
6028 mWindowManager.setEventDispatching(false);
6029
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006030 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006031
6032 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006033 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006034 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6035 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006036 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006037 }
6038 }
6039
Dianne Hackborn55280a92009-05-07 15:53:46 -07006040 public boolean shutdown(int timeout) {
6041 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6042 != PackageManager.PERMISSION_GRANTED) {
6043 throw new SecurityException("Requires permission "
6044 + android.Manifest.permission.SHUTDOWN);
6045 }
6046
6047 boolean timedout = false;
6048
6049 synchronized(this) {
6050 mShuttingDown = true;
6051 mWindowManager.setEventDispatching(false);
6052
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006053 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006054 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006055 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006056 while (mMainStack.mResumedActivity != null
6057 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006058 long delay = endTime - System.currentTimeMillis();
6059 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006060 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006061 timedout = true;
6062 break;
6063 }
6064 try {
6065 this.wait();
6066 } catch (InterruptedException e) {
6067 }
6068 }
6069 }
6070 }
6071
6072 mUsageStatsService.shutdown();
6073 mBatteryStatsService.shutdown();
6074
6075 return timedout;
6076 }
6077
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006078 public final void activitySlept(IBinder token) {
6079 if (localLOGV) Slog.v(
6080 TAG, "Activity slept: token=" + token);
6081
6082 ActivityRecord r = null;
6083
6084 final long origId = Binder.clearCallingIdentity();
6085
6086 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006087 r = mMainStack.isInStackLocked(token);
6088 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006089 mMainStack.activitySleptLocked(r);
6090 }
6091 }
6092
6093 Binder.restoreCallingIdentity(origId);
6094 }
6095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006096 public void wakingUp() {
6097 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098 mWindowManager.setEventDispatching(true);
6099 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006100 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006101 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006102 }
6103 }
6104
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006105 public void stopAppSwitches() {
6106 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6107 != PackageManager.PERMISSION_GRANTED) {
6108 throw new SecurityException("Requires permission "
6109 + android.Manifest.permission.STOP_APP_SWITCHES);
6110 }
6111
6112 synchronized(this) {
6113 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6114 + APP_SWITCH_DELAY_TIME;
6115 mDidAppSwitch = false;
6116 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6117 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6118 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6119 }
6120 }
6121
6122 public void resumeAppSwitches() {
6123 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6124 != PackageManager.PERMISSION_GRANTED) {
6125 throw new SecurityException("Requires permission "
6126 + android.Manifest.permission.STOP_APP_SWITCHES);
6127 }
6128
6129 synchronized(this) {
6130 // Note that we don't execute any pending app switches... we will
6131 // let those wait until either the timeout, or the next start
6132 // activity request.
6133 mAppSwitchesAllowedTime = 0;
6134 }
6135 }
6136
6137 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6138 String name) {
6139 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6140 return true;
6141 }
6142
6143 final int perm = checkComponentPermission(
6144 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006145 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006146 if (perm == PackageManager.PERMISSION_GRANTED) {
6147 return true;
6148 }
6149
Joe Onorato8a9b2202010-02-26 18:56:32 -08006150 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006151 return false;
6152 }
6153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006154 public void setDebugApp(String packageName, boolean waitForDebugger,
6155 boolean persistent) {
6156 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6157 "setDebugApp()");
6158
6159 // Note that this is not really thread safe if there are multiple
6160 // callers into it at the same time, but that's not a situation we
6161 // care about.
6162 if (persistent) {
6163 final ContentResolver resolver = mContext.getContentResolver();
6164 Settings.System.putString(
6165 resolver, Settings.System.DEBUG_APP,
6166 packageName);
6167 Settings.System.putInt(
6168 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6169 waitForDebugger ? 1 : 0);
6170 }
6171
6172 synchronized (this) {
6173 if (!persistent) {
6174 mOrigDebugApp = mDebugApp;
6175 mOrigWaitForDebugger = mWaitForDebugger;
6176 }
6177 mDebugApp = packageName;
6178 mWaitForDebugger = waitForDebugger;
6179 mDebugTransient = !persistent;
6180 if (packageName != null) {
6181 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006182 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006183 Binder.restoreCallingIdentity(origId);
6184 }
6185 }
6186 }
6187
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006188 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6189 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6190 synchronized (this) {
6191 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6192 if (!isDebuggable) {
6193 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6194 throw new SecurityException("Process not debuggable: " + app.packageName);
6195 }
6196 }
6197 mProfileApp = processName;
6198 mProfileFile = profileFile;
6199 if (mProfileFd != null) {
6200 try {
6201 mProfileFd.close();
6202 } catch (IOException e) {
6203 }
6204 mProfileFd = null;
6205 }
6206 mProfileFd = profileFd;
6207 mProfileType = 0;
6208 mAutoStopProfiler = autoStopProfiler;
6209 }
6210 }
6211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006212 public void setAlwaysFinish(boolean enabled) {
6213 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6214 "setAlwaysFinish()");
6215
6216 Settings.System.putInt(
6217 mContext.getContentResolver(),
6218 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6219
6220 synchronized (this) {
6221 mAlwaysFinishActivities = enabled;
6222 }
6223 }
6224
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006225 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006226 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006227 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006228 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006229 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006230 }
6231 }
6232
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006233 public boolean isUserAMonkey() {
6234 // For now the fact that there is a controller implies
6235 // we have a monkey.
6236 synchronized (this) {
6237 return mController != null;
6238 }
6239 }
6240
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006241 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006242 synchronized (this) {
6243 mWatchers.register(watcher);
6244 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006245 }
6246
6247 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006248 synchronized (this) {
6249 mWatchers.unregister(watcher);
6250 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006251 }
6252
Jeff Sharkeya4620792011-05-20 15:29:23 -07006253 public void registerProcessObserver(IProcessObserver observer) {
6254 mProcessObservers.register(observer);
6255 }
6256
6257 public void unregisterProcessObserver(IProcessObserver observer) {
6258 mProcessObservers.unregister(observer);
6259 }
6260
Daniel Sandler69a48172010-06-23 16:29:36 -04006261 public void setImmersive(IBinder token, boolean immersive) {
6262 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006263 ActivityRecord r = mMainStack.isInStackLocked(token);
6264 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006265 throw new IllegalArgumentException();
6266 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006267 r.immersive = immersive;
6268 }
6269 }
6270
6271 public boolean isImmersive(IBinder token) {
6272 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006273 ActivityRecord r = mMainStack.isInStackLocked(token);
6274 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006275 throw new IllegalArgumentException();
6276 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006277 return r.immersive;
6278 }
6279 }
6280
6281 public boolean isTopActivityImmersive() {
6282 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006283 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006284 return (r != null) ? r.immersive : false;
6285 }
6286 }
6287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006288 public final void enterSafeMode() {
6289 synchronized(this) {
6290 // It only makes sense to do this before the system is ready
6291 // and started launching other packages.
6292 if (!mSystemReady) {
6293 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006294 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006295 } catch (RemoteException e) {
6296 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006297 }
6298 }
6299 }
6300
Jeff Brownb09abc12011-01-13 21:08:27 -08006301 public final void showSafeModeOverlay() {
6302 View v = LayoutInflater.from(mContext).inflate(
6303 com.android.internal.R.layout.safe_mode, null);
6304 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6305 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6306 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6307 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6308 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6309 lp.format = v.getBackground().getOpacity();
6310 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6311 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6312 ((WindowManager)mContext.getSystemService(
6313 Context.WINDOW_SERVICE)).addView(v, lp);
6314 }
6315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006316 public void noteWakeupAlarm(IIntentSender sender) {
6317 if (!(sender instanceof PendingIntentRecord)) {
6318 return;
6319 }
6320 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6321 synchronized (stats) {
6322 if (mBatteryStatsService.isOnBattery()) {
6323 mBatteryStatsService.enforceCallingPermission();
6324 PendingIntentRecord rec = (PendingIntentRecord)sender;
6325 int MY_UID = Binder.getCallingUid();
6326 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6327 BatteryStatsImpl.Uid.Pkg pkg =
6328 stats.getPackageStatsLocked(uid, rec.key.packageName);
6329 pkg.incWakeupsLocked();
6330 }
6331 }
6332 }
6333
Dianne Hackborn64825172011-03-02 21:32:58 -08006334 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006335 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006336 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006337 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006338 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006339 // XXX Note: don't acquire main activity lock here, because the window
6340 // manager calls in with its locks held.
6341
6342 boolean killed = false;
6343 synchronized (mPidsSelfLocked) {
6344 int[] types = new int[pids.length];
6345 int worstType = 0;
6346 for (int i=0; i<pids.length; i++) {
6347 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6348 if (proc != null) {
6349 int type = proc.setAdj;
6350 types[i] = type;
6351 if (type > worstType) {
6352 worstType = type;
6353 }
6354 }
6355 }
6356
Dianne Hackborn64825172011-03-02 21:32:58 -08006357 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006358 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006359 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6360 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006361 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006362
6363 // If this is not a secure call, don't let it kill processes that
6364 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006365 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6366 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006367 }
6368
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006369 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006370 for (int i=0; i<pids.length; i++) {
6371 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6372 if (proc == null) {
6373 continue;
6374 }
6375 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006376 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006377 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006378 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6379 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006380 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006381 proc.killedBackground = true;
6382 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006383 }
6384 }
6385 }
6386 return killed;
6387 }
6388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006389 public final void startRunning(String pkg, String cls, String action,
6390 String data) {
6391 synchronized(this) {
6392 if (mStartRunning) {
6393 return;
6394 }
6395 mStartRunning = true;
6396 mTopComponent = pkg != null && cls != null
6397 ? new ComponentName(pkg, cls) : null;
6398 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6399 mTopData = data;
6400 if (!mSystemReady) {
6401 return;
6402 }
6403 }
6404
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006405 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006406 }
6407
6408 private void retrieveSettings() {
6409 final ContentResolver resolver = mContext.getContentResolver();
6410 String debugApp = Settings.System.getString(
6411 resolver, Settings.System.DEBUG_APP);
6412 boolean waitForDebugger = Settings.System.getInt(
6413 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6414 boolean alwaysFinishActivities = Settings.System.getInt(
6415 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6416
6417 Configuration configuration = new Configuration();
6418 Settings.System.getConfiguration(resolver, configuration);
6419
6420 synchronized (this) {
6421 mDebugApp = mOrigDebugApp = debugApp;
6422 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6423 mAlwaysFinishActivities = alwaysFinishActivities;
6424 // This happens before any activities are started, so we can
6425 // change mConfiguration in-place.
6426 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006427 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006428 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006429 }
6430 }
6431
6432 public boolean testIsSystemReady() {
6433 // no need to synchronize(this) just to read & return the value
6434 return mSystemReady;
6435 }
6436
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006437 private static File getCalledPreBootReceiversFile() {
6438 File dataDir = Environment.getDataDirectory();
6439 File systemDir = new File(dataDir, "system");
6440 File fname = new File(systemDir, "called_pre_boots.dat");
6441 return fname;
6442 }
6443
6444 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6445 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6446 File file = getCalledPreBootReceiversFile();
6447 FileInputStream fis = null;
6448 try {
6449 fis = new FileInputStream(file);
6450 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6451 int vers = dis.readInt();
6452 String codename = dis.readUTF();
6453 if (vers == android.os.Build.VERSION.SDK_INT
6454 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6455 int num = dis.readInt();
6456 while (num > 0) {
6457 num--;
6458 String pkg = dis.readUTF();
6459 String cls = dis.readUTF();
6460 lastDoneReceivers.add(new ComponentName(pkg, cls));
6461 }
6462 }
6463 } catch (FileNotFoundException e) {
6464 } catch (IOException e) {
6465 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6466 } finally {
6467 if (fis != null) {
6468 try {
6469 fis.close();
6470 } catch (IOException e) {
6471 }
6472 }
6473 }
6474 return lastDoneReceivers;
6475 }
6476
6477 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6478 File file = getCalledPreBootReceiversFile();
6479 FileOutputStream fos = null;
6480 DataOutputStream dos = null;
6481 try {
6482 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6483 fos = new FileOutputStream(file);
6484 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6485 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6486 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6487 dos.writeInt(list.size());
6488 for (int i=0; i<list.size(); i++) {
6489 dos.writeUTF(list.get(i).getPackageName());
6490 dos.writeUTF(list.get(i).getClassName());
6491 }
6492 } catch (IOException e) {
6493 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6494 file.delete();
6495 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006496 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006497 if (dos != null) {
6498 try {
6499 dos.close();
6500 } catch (IOException e) {
6501 // TODO Auto-generated catch block
6502 e.printStackTrace();
6503 }
6504 }
6505 }
6506 }
6507
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006508 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006509 synchronized(this) {
6510 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006511 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006512 return;
6513 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006514
6515 // Check to see if there are any update receivers to run.
6516 if (!mDidUpdate) {
6517 if (mWaitingUpdate) {
6518 return;
6519 }
6520 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6521 List<ResolveInfo> ris = null;
6522 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006523 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006524 intent, null, 0);
6525 } catch (RemoteException e) {
6526 }
6527 if (ris != null) {
6528 for (int i=ris.size()-1; i>=0; i--) {
6529 if ((ris.get(i).activityInfo.applicationInfo.flags
6530 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6531 ris.remove(i);
6532 }
6533 }
6534 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006535
6536 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6537
6538 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006539 for (int i=0; i<ris.size(); i++) {
6540 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006541 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6542 if (lastDoneReceivers.contains(comp)) {
6543 ris.remove(i);
6544 i--;
6545 }
6546 }
6547
6548 for (int i=0; i<ris.size(); i++) {
6549 ActivityInfo ai = ris.get(i).activityInfo;
6550 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6551 doneReceivers.add(comp);
6552 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006553 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006554 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006555 finisher = new IIntentReceiver.Stub() {
6556 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006557 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006558 boolean sticky) {
6559 // The raw IIntentReceiver interface is called
6560 // with the AM lock held, so redispatch to
6561 // execute our code without the lock.
6562 mHandler.post(new Runnable() {
6563 public void run() {
6564 synchronized (ActivityManagerService.this) {
6565 mDidUpdate = true;
6566 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006567 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006568 systemReady(goingCallback);
6569 }
6570 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006571 }
6572 };
6573 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006574 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006575 broadcastIntentLocked(null, null, intent, null, finisher,
6576 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006577 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006578 mWaitingUpdate = true;
6579 }
6580 }
6581 }
6582 if (mWaitingUpdate) {
6583 return;
6584 }
6585 mDidUpdate = true;
6586 }
6587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006588 mSystemReady = true;
6589 if (!mStartRunning) {
6590 return;
6591 }
6592 }
6593
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006594 ArrayList<ProcessRecord> procsToKill = null;
6595 synchronized(mPidsSelfLocked) {
6596 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6597 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6598 if (!isAllowedWhileBooting(proc.info)){
6599 if (procsToKill == null) {
6600 procsToKill = new ArrayList<ProcessRecord>();
6601 }
6602 procsToKill.add(proc);
6603 }
6604 }
6605 }
6606
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006607 synchronized(this) {
6608 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006609 for (int i=procsToKill.size()-1; i>=0; i--) {
6610 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006611 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006612 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006613 }
6614 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006615
6616 // Now that we have cleaned up any update processes, we
6617 // are ready to start launching real processes and know that
6618 // we won't trample on them any more.
6619 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006620 }
6621
Joe Onorato8a9b2202010-02-26 18:56:32 -08006622 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006623 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006624 SystemClock.uptimeMillis());
6625
6626 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006627 // Make sure we have no pre-ready processes sitting around.
6628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006629 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6630 ResolveInfo ri = mContext.getPackageManager()
6631 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006632 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006633 CharSequence errorMsg = null;
6634 if (ri != null) {
6635 ActivityInfo ai = ri.activityInfo;
6636 ApplicationInfo app = ai.applicationInfo;
6637 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6638 mTopAction = Intent.ACTION_FACTORY_TEST;
6639 mTopData = null;
6640 mTopComponent = new ComponentName(app.packageName,
6641 ai.name);
6642 } else {
6643 errorMsg = mContext.getResources().getText(
6644 com.android.internal.R.string.factorytest_not_system);
6645 }
6646 } else {
6647 errorMsg = mContext.getResources().getText(
6648 com.android.internal.R.string.factorytest_no_action);
6649 }
6650 if (errorMsg != null) {
6651 mTopAction = null;
6652 mTopData = null;
6653 mTopComponent = null;
6654 Message msg = Message.obtain();
6655 msg.what = SHOW_FACTORY_ERROR_MSG;
6656 msg.getData().putCharSequence("msg", errorMsg);
6657 mHandler.sendMessage(msg);
6658 }
6659 }
6660 }
6661
6662 retrieveSettings();
6663
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006664 if (goingCallback != null) goingCallback.run();
6665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006666 synchronized (this) {
6667 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6668 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006669 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006670 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006671 if (apps != null) {
6672 int N = apps.size();
6673 int i;
6674 for (i=0; i<N; i++) {
6675 ApplicationInfo info
6676 = (ApplicationInfo)apps.get(i);
6677 if (info != null &&
6678 !info.packageName.equals("android")) {
6679 addAppLocked(info);
6680 }
6681 }
6682 }
6683 } catch (RemoteException ex) {
6684 // pm is in same process, this will never happen.
6685 }
6686 }
6687
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006688 // Start up initial activity.
6689 mBooting = true;
6690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006691 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006692 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006693 Message msg = Message.obtain();
6694 msg.what = SHOW_UID_ERROR_MSG;
6695 mHandler.sendMessage(msg);
6696 }
6697 } catch (RemoteException e) {
6698 }
6699
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006700 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006701 }
6702 }
6703
Dan Egnorb7f03672009-12-09 16:22:32 -08006704 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006705 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006706 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006707 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006708 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006709 startAppProblemLocked(app);
6710 app.stopFreezingAllLocked();
6711 return handleAppCrashLocked(app);
6712 }
6713
Dan Egnorb7f03672009-12-09 16:22:32 -08006714 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006715 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006716 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006717 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006718 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6719 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006720 startAppProblemLocked(app);
6721 app.stopFreezingAllLocked();
6722 }
6723
6724 /**
6725 * Generate a process error record, suitable for attachment to a ProcessRecord.
6726 *
6727 * @param app The ProcessRecord in which the error occurred.
6728 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6729 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006730 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006731 * @param shortMsg Short message describing the crash.
6732 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006733 * @param stackTrace Full crash stack trace, may be null.
6734 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006735 * @return Returns a fully-formed AppErrorStateInfo record.
6736 */
6737 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006738 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006739 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006741 report.condition = condition;
6742 report.processName = app.processName;
6743 report.pid = app.pid;
6744 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006745 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006746 report.shortMsg = shortMsg;
6747 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006748 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006749
6750 return report;
6751 }
6752
Dan Egnor42471dd2010-01-07 17:25:22 -08006753 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006754 synchronized (this) {
6755 app.crashing = false;
6756 app.crashingReport = null;
6757 app.notResponding = false;
6758 app.notRespondingReport = null;
6759 if (app.anrDialog == fromDialog) {
6760 app.anrDialog = null;
6761 }
6762 if (app.waitDialog == fromDialog) {
6763 app.waitDialog = null;
6764 }
6765 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006766 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006767 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006768 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6769 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006770 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006772 }
6773 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006774
Dan Egnorb7f03672009-12-09 16:22:32 -08006775 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006776 long now = SystemClock.uptimeMillis();
6777
6778 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6779 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006780 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006781 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006782 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006783 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006784 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006785 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006786 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6787 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006788 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006789 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006790 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006791 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006792 }
6793 }
6794 if (!app.persistent) {
6795 // We don't want to start this process again until the user
6796 // explicitly does so... but for persistent process, we really
6797 // need to keep it running. If a persistent process is actually
6798 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006799 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006800 app.info.processName);
6801 mBadProcesses.put(app.info.processName, app.info.uid, now);
6802 app.bad = true;
6803 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6804 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006805 // Don't let services in this process be restarted and potentially
6806 // annoy the user repeatedly. Unless it is persistent, since those
6807 // processes run critical code.
6808 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006809 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006810 return false;
6811 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006812 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006813 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006814 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006815 if (r.app == app) {
6816 // If the top running activity is from this crashing
6817 // process, then terminate it to avoid getting in a loop.
6818 Slog.w(TAG, " Force finishing activity "
6819 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006820 int index = mMainStack.indexOfTokenLocked(r);
6821 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006822 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006823 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006824 // stopped, to avoid a situation where one will get
6825 // re-start our crashing activity once it gets resumed again.
6826 index--;
6827 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006828 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006829 if (r.state == ActivityState.RESUMED
6830 || r.state == ActivityState.PAUSING
6831 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006832 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006833 Slog.w(TAG, " Force finishing activity "
6834 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006835 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006836 Activity.RESULT_CANCELED, null, "crashed");
6837 }
6838 }
6839 }
6840 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006841 }
6842
6843 // Bump up the crash count of any services currently running in the proc.
6844 if (app.services.size() != 0) {
6845 // Any services running in the application need to be placed
6846 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006847 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006848 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006849 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006850 sr.crashCount++;
6851 }
6852 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006853
6854 // If the crashing process is what we consider to be the "home process" and it has been
6855 // replaced by a third-party app, clear the package preferred activities from packages
6856 // with a home activity running in the process to prevent a repeatedly crashing app
6857 // from blocking the user to manually clear the list.
6858 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6859 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6860 Iterator it = mHomeProcess.activities.iterator();
6861 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006862 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006863 if (r.isHomeActivity) {
6864 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6865 try {
6866 ActivityThread.getPackageManager()
6867 .clearPackagePreferredActivities(r.packageName);
6868 } catch (RemoteException c) {
6869 // pm is in same process, this will never happen.
6870 }
6871 }
6872 }
6873 }
6874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006875 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6876 return true;
6877 }
6878
6879 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006880 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6881 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006882 skipCurrentReceiverLocked(app);
6883 }
6884
6885 void skipCurrentReceiverLocked(ProcessRecord app) {
6886 boolean reschedule = false;
6887 BroadcastRecord r = app.curReceiver;
6888 if (r != null) {
6889 // The current broadcast is waiting for this app's receiver
6890 // to be finished. Looks like that's not going to happen, so
6891 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006892 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006893 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6894 r.resultExtras, r.resultAbort, true);
6895 reschedule = true;
6896 }
6897 r = mPendingBroadcast;
6898 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006899 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006900 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006901 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006902 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6903 r.resultExtras, r.resultAbort, true);
6904 reschedule = true;
6905 }
6906 if (reschedule) {
6907 scheduleBroadcastsLocked();
6908 }
6909 }
6910
Dan Egnor60d87622009-12-16 16:32:58 -08006911 /**
6912 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6913 * The application process will exit immediately after this call returns.
6914 * @param app object of the crashing app, null for the system server
6915 * @param crashInfo describing the exception
6916 */
6917 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006918 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006919
6920 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6921 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006922 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006923 crashInfo.exceptionClassName,
6924 crashInfo.exceptionMessage,
6925 crashInfo.throwFileName,
6926 crashInfo.throwLineNumber);
6927
Dan Egnor42471dd2010-01-07 17:25:22 -08006928 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006929
6930 crashApplication(r, crashInfo);
6931 }
6932
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006933 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006934 IBinder app,
6935 int violationMask,
6936 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006937 ProcessRecord r = findAppProcess(app, "StrictMode");
6938 if (r == null) {
6939 return;
6940 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006941
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006942 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006943 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006944 boolean logIt = true;
6945 synchronized (mAlreadyLoggedViolatedStacks) {
6946 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6947 logIt = false;
6948 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006949 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006950 // the relative pain numbers, without logging all
6951 // the stack traces repeatedly. We'd want to do
6952 // likewise in the client code, which also does
6953 // dup suppression, before the Binder call.
6954 } else {
6955 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6956 mAlreadyLoggedViolatedStacks.clear();
6957 }
6958 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6959 }
6960 }
6961 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006962 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006963 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006964 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006965
6966 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6967 AppErrorResult result = new AppErrorResult();
6968 synchronized (this) {
6969 final long origId = Binder.clearCallingIdentity();
6970
6971 Message msg = Message.obtain();
6972 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6973 HashMap<String, Object> data = new HashMap<String, Object>();
6974 data.put("result", result);
6975 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006976 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006977 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006978 msg.obj = data;
6979 mHandler.sendMessage(msg);
6980
6981 Binder.restoreCallingIdentity(origId);
6982 }
6983 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07006984 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006985 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006986 }
6987
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006988 // Depending on the policy in effect, there could be a bunch of
6989 // these in quick succession so we try to batch these together to
6990 // minimize disk writes, number of dropbox entries, and maximize
6991 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006992 private void logStrictModeViolationToDropBox(
6993 ProcessRecord process,
6994 StrictMode.ViolationInfo info) {
6995 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006996 return;
6997 }
6998 final boolean isSystemApp = process == null ||
6999 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7000 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7001 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7002 final DropBoxManager dbox = (DropBoxManager)
7003 mContext.getSystemService(Context.DROPBOX_SERVICE);
7004
7005 // Exit early if the dropbox isn't configured to accept this report type.
7006 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7007
7008 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007009 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007010 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7011 synchronized (sb) {
7012 bufferWasEmpty = sb.length() == 0;
7013 appendDropBoxProcessHeaders(process, sb);
7014 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7015 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007016 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7017 if (info.violationNumThisLoop != 0) {
7018 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7019 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007020 if (info.numAnimationsRunning != 0) {
7021 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7022 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007023 if (info.broadcastIntentAction != null) {
7024 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7025 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007026 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007027 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007028 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007029 if (info.numInstances != -1) {
7030 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7031 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007032 if (info.tags != null) {
7033 for (String tag : info.tags) {
7034 sb.append("Span-Tag: ").append(tag).append("\n");
7035 }
7036 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007037 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007038 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7039 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007040 }
7041 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007042
7043 // Only buffer up to ~64k. Various logging bits truncate
7044 // things at 128k.
7045 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007046 }
7047
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007048 // Flush immediately if the buffer's grown too large, or this
7049 // is a non-system app. Non-system apps are isolated with a
7050 // different tag & policy and not batched.
7051 //
7052 // Batching is useful during internal testing with
7053 // StrictMode settings turned up high. Without batching,
7054 // thousands of separate files could be created on boot.
7055 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007056 new Thread("Error dump: " + dropboxTag) {
7057 @Override
7058 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007059 String report;
7060 synchronized (sb) {
7061 report = sb.toString();
7062 sb.delete(0, sb.length());
7063 sb.trimToSize();
7064 }
7065 if (report.length() != 0) {
7066 dbox.addText(dropboxTag, report);
7067 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007068 }
7069 }.start();
7070 return;
7071 }
7072
7073 // System app batching:
7074 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007075 // An existing dropbox-writing thread is outstanding, so
7076 // we don't need to start it up. The existing thread will
7077 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007078 return;
7079 }
7080
7081 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7082 // (After this point, we shouldn't access AMS internal data structures.)
7083 new Thread("Error dump: " + dropboxTag) {
7084 @Override
7085 public void run() {
7086 // 5 second sleep to let stacks arrive and be batched together
7087 try {
7088 Thread.sleep(5000); // 5 seconds
7089 } catch (InterruptedException e) {}
7090
7091 String errorReport;
7092 synchronized (mStrictModeBuffer) {
7093 errorReport = mStrictModeBuffer.toString();
7094 if (errorReport.length() == 0) {
7095 return;
7096 }
7097 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7098 mStrictModeBuffer.trimToSize();
7099 }
7100 dbox.addText(dropboxTag, errorReport);
7101 }
7102 }.start();
7103 }
7104
Dan Egnor60d87622009-12-16 16:32:58 -08007105 /**
7106 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7107 * @param app object of the crashing app, null for the system server
7108 * @param tag reported by the caller
7109 * @param crashInfo describing the context of the error
7110 * @return true if the process should exit immediately (WTF is fatal)
7111 */
7112 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007113 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007114 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007115
7116 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7117 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007118 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007119 tag, crashInfo.exceptionMessage);
7120
Dan Egnor42471dd2010-01-07 17:25:22 -08007121 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007122
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007123 if (r != null && r.pid != Process.myPid() &&
7124 Settings.Secure.getInt(mContext.getContentResolver(),
7125 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007126 crashApplication(r, crashInfo);
7127 return true;
7128 } else {
7129 return false;
7130 }
7131 }
7132
7133 /**
7134 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7135 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7136 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007137 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007138 if (app == null) {
7139 return null;
7140 }
7141
7142 synchronized (this) {
7143 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7144 final int NA = apps.size();
7145 for (int ia=0; ia<NA; ia++) {
7146 ProcessRecord p = apps.valueAt(ia);
7147 if (p.thread != null && p.thread.asBinder() == app) {
7148 return p;
7149 }
7150 }
7151 }
7152
Dianne Hackborncb44d962011-03-10 17:02:27 -08007153 Slog.w(TAG, "Can't find mystery application for " + reason
7154 + " from pid=" + Binder.getCallingPid()
7155 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007156 return null;
7157 }
7158 }
7159
7160 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007161 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7162 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007163 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007164 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007165 // Watchdog thread ends up invoking this function (with
7166 // a null ProcessRecord) to add the stack file to dropbox.
7167 // Do not acquire a lock on this (am) in such cases, as it
7168 // could cause a potential deadlock, if and when watchdog
7169 // is invoked due to unavailability of lock on am and it
7170 // would prevent watchdog from killing system_server.
7171 if (process == null) {
7172 sb.append("Process: system_server\n");
7173 return;
7174 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007175 // Note: ProcessRecord 'process' is guarded by the service
7176 // instance. (notably process.pkgList, which could otherwise change
7177 // concurrently during execution of this method)
7178 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007179 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007180 sb.append("Process: system_server\n");
7181 } else {
7182 sb.append("Process: ").append(process.processName).append("\n");
7183 }
Dan Egnora455d192010-03-12 08:52:28 -08007184 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007185 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007186 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7187 for (String pkg : process.pkgList) {
7188 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007189 try {
Dan Egnora455d192010-03-12 08:52:28 -08007190 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7191 if (pi != null) {
7192 sb.append(" v").append(pi.versionCode);
7193 if (pi.versionName != null) {
7194 sb.append(" (").append(pi.versionName).append(")");
7195 }
7196 }
7197 } catch (RemoteException e) {
7198 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007199 }
Dan Egnora455d192010-03-12 08:52:28 -08007200 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007201 }
Dan Egnora455d192010-03-12 08:52:28 -08007202 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007203 }
7204
7205 private static String processClass(ProcessRecord process) {
7206 if (process == null || process.pid == MY_PID) {
7207 return "system_server";
7208 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7209 return "system_app";
7210 } else {
7211 return "data_app";
7212 }
7213 }
7214
7215 /**
7216 * Write a description of an error (crash, WTF, ANR) to the drop box.
7217 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7218 * @param process which caused the error, null means the system server
7219 * @param activity which triggered the error, null if unknown
7220 * @param parent activity related to the error, null if unknown
7221 * @param subject line related to the error, null if absent
7222 * @param report in long form describing the error, null if absent
7223 * @param logFile to include in the report, null if none
7224 * @param crashInfo giving an application stack trace, null if absent
7225 */
7226 public void addErrorToDropBox(String eventType,
7227 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7228 final String report, final File logFile,
7229 final ApplicationErrorReport.CrashInfo crashInfo) {
7230 // NOTE -- this must never acquire the ActivityManagerService lock,
7231 // otherwise the watchdog may be prevented from resetting the system.
7232
7233 final String dropboxTag = processClass(process) + "_" + eventType;
7234 final DropBoxManager dbox = (DropBoxManager)
7235 mContext.getSystemService(Context.DROPBOX_SERVICE);
7236
7237 // Exit early if the dropbox isn't configured to accept this report type.
7238 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7239
7240 final StringBuilder sb = new StringBuilder(1024);
7241 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007242 if (activity != null) {
7243 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7244 }
7245 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7246 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7247 }
7248 if (parent != null && parent != activity) {
7249 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7250 }
7251 if (subject != null) {
7252 sb.append("Subject: ").append(subject).append("\n");
7253 }
7254 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007255 if (Debug.isDebuggerConnected()) {
7256 sb.append("Debugger: Connected\n");
7257 }
Dan Egnora455d192010-03-12 08:52:28 -08007258 sb.append("\n");
7259
7260 // Do the rest in a worker thread to avoid blocking the caller on I/O
7261 // (After this point, we shouldn't access AMS internal data structures.)
7262 Thread worker = new Thread("Error dump: " + dropboxTag) {
7263 @Override
7264 public void run() {
7265 if (report != null) {
7266 sb.append(report);
7267 }
7268 if (logFile != null) {
7269 try {
7270 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7271 } catch (IOException e) {
7272 Slog.e(TAG, "Error reading " + logFile, e);
7273 }
7274 }
7275 if (crashInfo != null && crashInfo.stackTrace != null) {
7276 sb.append(crashInfo.stackTrace);
7277 }
7278
7279 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7280 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7281 if (lines > 0) {
7282 sb.append("\n");
7283
7284 // Merge several logcat streams, and take the last N lines
7285 InputStreamReader input = null;
7286 try {
7287 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7288 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7289 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7290
7291 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7292 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7293 input = new InputStreamReader(logcat.getInputStream());
7294
7295 int num;
7296 char[] buf = new char[8192];
7297 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7298 } catch (IOException e) {
7299 Slog.e(TAG, "Error running logcat", e);
7300 } finally {
7301 if (input != null) try { input.close(); } catch (IOException e) {}
7302 }
7303 }
7304
7305 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007306 }
Dan Egnora455d192010-03-12 08:52:28 -08007307 };
7308
7309 if (process == null || process.pid == MY_PID) {
7310 worker.run(); // We may be about to die -- need to run this synchronously
7311 } else {
7312 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007313 }
7314 }
7315
7316 /**
7317 * Bring up the "unexpected error" dialog box for a crashing app.
7318 * Deal with edge cases (intercepts from instrumented applications,
7319 * ActivityController, error intent receivers, that sort of thing).
7320 * @param r the application crashing
7321 * @param crashInfo describing the failure
7322 */
7323 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007324 long timeMillis = System.currentTimeMillis();
7325 String shortMsg = crashInfo.exceptionClassName;
7326 String longMsg = crashInfo.exceptionMessage;
7327 String stackTrace = crashInfo.stackTrace;
7328 if (shortMsg != null && longMsg != null) {
7329 longMsg = shortMsg + ": " + longMsg;
7330 } else if (shortMsg != null) {
7331 longMsg = shortMsg;
7332 }
7333
Dan Egnor60d87622009-12-16 16:32:58 -08007334 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007335 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007336 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007337 try {
7338 String name = r != null ? r.processName : null;
7339 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007340 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007341 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007342 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007343 + " at watcher's request");
7344 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007345 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007346 }
7347 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007348 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007349 }
7350 }
7351
7352 final long origId = Binder.clearCallingIdentity();
7353
7354 // If this process is running instrumentation, finish it.
7355 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007356 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007357 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007358 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7359 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007360 Bundle info = new Bundle();
7361 info.putString("shortMsg", shortMsg);
7362 info.putString("longMsg", longMsg);
7363 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7364 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007365 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007366 }
7367
Dan Egnor60d87622009-12-16 16:32:58 -08007368 // If we can't identify the process or it's already exceeded its crash quota,
7369 // quit right away without showing a crash dialog.
7370 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007371 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007372 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007373 }
7374
7375 Message msg = Message.obtain();
7376 msg.what = SHOW_ERROR_MSG;
7377 HashMap data = new HashMap();
7378 data.put("result", result);
7379 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007380 msg.obj = data;
7381 mHandler.sendMessage(msg);
7382
7383 Binder.restoreCallingIdentity(origId);
7384 }
7385
7386 int res = result.get();
7387
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007388 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007389 synchronized (this) {
7390 if (r != null) {
7391 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7392 SystemClock.uptimeMillis());
7393 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007394 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007395 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007396 }
7397 }
7398
7399 if (appErrorIntent != null) {
7400 try {
7401 mContext.startActivity(appErrorIntent);
7402 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007403 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007406 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007407
7408 Intent createAppErrorIntentLocked(ProcessRecord r,
7409 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7410 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007411 if (report == null) {
7412 return null;
7413 }
7414 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7415 result.setComponent(r.errorReportReceiver);
7416 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7417 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7418 return result;
7419 }
7420
Dan Egnorb7f03672009-12-09 16:22:32 -08007421 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7422 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007423 if (r.errorReportReceiver == null) {
7424 return null;
7425 }
7426
7427 if (!r.crashing && !r.notResponding) {
7428 return null;
7429 }
7430
Dan Egnorb7f03672009-12-09 16:22:32 -08007431 ApplicationErrorReport report = new ApplicationErrorReport();
7432 report.packageName = r.info.packageName;
7433 report.installerPackageName = r.errorReportReceiver.getPackageName();
7434 report.processName = r.processName;
7435 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007436 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007437
Dan Egnorb7f03672009-12-09 16:22:32 -08007438 if (r.crashing) {
7439 report.type = ApplicationErrorReport.TYPE_CRASH;
7440 report.crashInfo = crashInfo;
7441 } else if (r.notResponding) {
7442 report.type = ApplicationErrorReport.TYPE_ANR;
7443 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007444
Dan Egnorb7f03672009-12-09 16:22:32 -08007445 report.anrInfo.activity = r.notRespondingReport.tag;
7446 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7447 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007448 }
7449
Dan Egnorb7f03672009-12-09 16:22:32 -08007450 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007451 }
7452
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007453 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7454 // assume our apps are happy - lazy create the list
7455 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7456
7457 synchronized (this) {
7458
7459 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007460 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7461 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007462 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7463 // This one's in trouble, so we'll generate a report for it
7464 // crashes are higher priority (in case there's a crash *and* an anr)
7465 ActivityManager.ProcessErrorStateInfo report = null;
7466 if (app.crashing) {
7467 report = app.crashingReport;
7468 } else if (app.notResponding) {
7469 report = app.notRespondingReport;
7470 }
7471
7472 if (report != null) {
7473 if (errList == null) {
7474 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7475 }
7476 errList.add(report);
7477 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007478 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007479 " crashing = " + app.crashing +
7480 " notResponding = " + app.notResponding);
7481 }
7482 }
7483 }
7484 }
7485
7486 return errList;
7487 }
7488
7489 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7490 // Lazy instantiation of list
7491 List<ActivityManager.RunningAppProcessInfo> runList = null;
7492 synchronized (this) {
7493 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007494 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7495 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007496 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7497 // Generate process state info for running application
7498 ActivityManager.RunningAppProcessInfo currApp =
7499 new ActivityManager.RunningAppProcessInfo(app.processName,
7500 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007501 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007502 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007503 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007504 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007505 if (app.persistent) {
7506 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7507 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007508 int adj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007509 if (adj >= ProcessList.EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007510 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007511 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007512 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007513 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7514 } else if (adj >= ProcessList.HOME_APP_ADJ) {
The Android Open Source Project4df24232009-03-05 14:34:35 -08007515 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7516 currApp.lru = 0;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007517 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007518 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007519 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007520 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007521 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007522 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007523 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007524 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7525 } else {
7526 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7527 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007528 currApp.importanceReasonCode = app.adjTypeCode;
7529 if (app.adjSource instanceof ProcessRecord) {
7530 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007531 } else if (app.adjSource instanceof ActivityRecord) {
7532 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007533 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7534 }
7535 if (app.adjTarget instanceof ComponentName) {
7536 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7537 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007538 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007539 // + " lru=" + currApp.lru);
7540 if (runList == null) {
7541 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7542 }
7543 runList.add(currApp);
7544 }
7545 }
7546 }
7547 return runList;
7548 }
7549
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007550 public List<ApplicationInfo> getRunningExternalApplications() {
7551 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7552 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7553 if (runningApps != null && runningApps.size() > 0) {
7554 Set<String> extList = new HashSet<String>();
7555 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7556 if (app.pkgList != null) {
7557 for (String pkg : app.pkgList) {
7558 extList.add(pkg);
7559 }
7560 }
7561 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007562 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007563 for (String pkg : extList) {
7564 try {
7565 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7566 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7567 retList.add(info);
7568 }
7569 } catch (RemoteException e) {
7570 }
7571 }
7572 }
7573 return retList;
7574 }
7575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007576 @Override
7577 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007578 if (checkCallingPermission(android.Manifest.permission.DUMP)
7579 != PackageManager.PERMISSION_GRANTED) {
7580 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7581 + Binder.getCallingPid()
7582 + ", uid=" + Binder.getCallingUid()
7583 + " without permission "
7584 + android.Manifest.permission.DUMP);
7585 return;
7586 }
7587
7588 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007589 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007590
7591 int opti = 0;
7592 while (opti < args.length) {
7593 String opt = args[opti];
7594 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7595 break;
7596 }
7597 opti++;
7598 if ("-a".equals(opt)) {
7599 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007600 } else if ("-c".equals(opt)) {
7601 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007602 } else if ("-h".equals(opt)) {
7603 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007604 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007605 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007606 pw.println(" a[ctivities]: activity stack state");
7607 pw.println(" b[roadcasts]: broadcast state");
7608 pw.println(" i[ntents]: pending intent state");
7609 pw.println(" p[rocesses]: process state");
7610 pw.println(" o[om]: out of memory management");
7611 pw.println(" prov[iders]: content provider state");
7612 pw.println(" s[ervices]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007613 pw.println(" service [COMP_SPEC]: service client-side state");
7614 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
7615 pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),");
7616 pw.println(" a partial substring in a component name, an");
7617 pw.println(" ActivityRecord hex object identifier, or");
Dianne Hackbornf9302322011-06-14 18:36:14 -07007618 pw.println(" \"all\" for all objects, or");
7619 pw.println(" \"top\" for the top activity.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007620 pw.println(" -a: include all available server state.");
7621 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007622 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007623 } else {
7624 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007625 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007626 }
7627
7628 // Is the caller requesting to dump a particular piece of data?
7629 if (opti < args.length) {
7630 String cmd = args[opti];
7631 opti++;
7632 if ("activities".equals(cmd) || "a".equals(cmd)) {
7633 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007634 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007635 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007636 return;
7637 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7638 synchronized (this) {
7639 dumpBroadcastsLocked(fd, pw, args, opti, true);
7640 }
7641 return;
7642 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7643 synchronized (this) {
7644 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7645 }
7646 return;
7647 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7648 synchronized (this) {
7649 dumpProcessesLocked(fd, pw, args, opti, true);
7650 }
7651 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007652 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7653 synchronized (this) {
7654 dumpOomLocked(fd, pw, args, opti, true);
7655 }
7656 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007657 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7658 synchronized (this) {
7659 dumpProvidersLocked(fd, pw, args, opti, true);
7660 }
7661 return;
7662 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007663 String[] newArgs;
7664 String name;
7665 if (opti >= args.length) {
7666 name = null;
7667 newArgs = EMPTY_STRING_ARRAY;
7668 } else {
7669 name = args[opti];
7670 opti++;
7671 newArgs = new String[args.length - opti];
7672 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7673 }
7674 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7675 pw.println("No services match: " + name);
7676 pw.println("Use -h for help.");
7677 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007678 return;
7679 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7680 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007681 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007682 }
7683 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007684 } else {
7685 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007686 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7687 pw.println("Bad activity command, or no activities match: " + cmd);
7688 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007689 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007690 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007691 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007692 }
7693
7694 // No piece of data specified, dump everything.
7695 synchronized (this) {
7696 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007697 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007698 if (needSep) {
7699 pw.println(" ");
7700 }
7701 if (dumpAll) {
7702 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007703 }
7704 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7705 if (needSep) {
7706 pw.println(" ");
7707 }
7708 if (dumpAll) {
7709 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007710 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007711 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007712 if (needSep) {
7713 pw.println(" ");
7714 }
7715 if (dumpAll) {
7716 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007717 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007718 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007719 if (needSep) {
7720 pw.println(" ");
7721 }
7722 if (dumpAll) {
7723 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007724 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007725 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007726 if (needSep) {
7727 pw.println(" ");
7728 }
7729 if (dumpAll) {
7730 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007731 }
7732 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7733 }
7734 }
7735
7736 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007737 int opti, boolean dumpAll, boolean dumpClient) {
7738 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7739 pw.println(" Main stack:");
7740 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007741 pw.println(" ");
7742 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007743 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007744 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007745 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007746 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007747 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7748 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007749 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007750 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007751 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007752 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007753 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7754 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007755 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007756 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7757 pw.println(" ");
7758 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007759 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7760 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007761 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007762 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007763 pw.println(" ");
7764 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007765 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7766 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007768
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007769 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007770 if (mMainStack.mPausingActivity != null) {
7771 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7772 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007773 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007774 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007775 if (dumpAll) {
7776 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7777 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7778 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007779
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007780 if (mRecentTasks.size() > 0) {
7781 pw.println();
7782 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007783
7784 final int N = mRecentTasks.size();
7785 for (int i=0; i<N; i++) {
7786 TaskRecord tr = mRecentTasks.get(i);
7787 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7788 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007789 if (dumpAll) {
7790 mRecentTasks.get(i).dump(pw, " ");
7791 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007792 }
7793 }
7794
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007795 if (dumpAll) {
7796 pw.println(" ");
7797 pw.println(" mCurTask: " + mCurTask);
7798 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007799
7800 return true;
7801 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007802
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007803 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7804 int opti, boolean dumpAll) {
7805 boolean needSep = false;
7806 int numPers = 0;
7807
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007808 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7809
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007810 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007811 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7812 final int NA = procs.size();
7813 for (int ia=0; ia<NA; ia++) {
7814 if (!needSep) {
7815 pw.println(" All known processes:");
7816 needSep = true;
7817 }
7818 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007819 pw.print(r.persistent ? " *PERS*" : " *APP*");
7820 pw.print(" UID "); pw.print(procs.keyAt(ia));
7821 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007822 r.dump(pw, " ");
7823 if (r.persistent) {
7824 numPers++;
7825 }
7826 }
7827 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007828 }
7829
7830 if (mLruProcesses.size() > 0) {
7831 if (needSep) pw.println(" ");
7832 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007833 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007834 dumpProcessOomList(pw, this, mLruProcesses, " ",
7835 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007836 needSep = true;
7837 }
7838
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007839 if (dumpAll) {
7840 synchronized (mPidsSelfLocked) {
7841 if (mPidsSelfLocked.size() > 0) {
7842 if (needSep) pw.println(" ");
7843 needSep = true;
7844 pw.println(" PID mappings:");
7845 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7846 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7847 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7848 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007849 }
7850 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007851 }
7852
7853 if (mForegroundProcesses.size() > 0) {
7854 if (needSep) pw.println(" ");
7855 needSep = true;
7856 pw.println(" Foreground Processes:");
7857 for (int i=0; i<mForegroundProcesses.size(); i++) {
7858 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7859 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007860 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007861 }
7862
7863 if (mPersistentStartingProcesses.size() > 0) {
7864 if (needSep) pw.println(" ");
7865 needSep = true;
7866 pw.println(" Persisent processes that are starting:");
7867 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007868 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007869 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007870
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007871 if (mRemovedProcesses.size() > 0) {
7872 if (needSep) pw.println(" ");
7873 needSep = true;
7874 pw.println(" Processes that are being removed:");
7875 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007876 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007877 }
7878
7879 if (mProcessesOnHold.size() > 0) {
7880 if (needSep) pw.println(" ");
7881 needSep = true;
7882 pw.println(" Processes that are on old until the system is ready:");
7883 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007884 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007885 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007886
Dianne Hackborn287952c2010-09-22 22:34:31 -07007887 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007888
7889 if (mProcessCrashTimes.getMap().size() > 0) {
7890 if (needSep) pw.println(" ");
7891 needSep = true;
7892 pw.println(" Time since processes crashed:");
7893 long now = SystemClock.uptimeMillis();
7894 for (Map.Entry<String, SparseArray<Long>> procs
7895 : mProcessCrashTimes.getMap().entrySet()) {
7896 SparseArray<Long> uids = procs.getValue();
7897 final int N = uids.size();
7898 for (int i=0; i<N; i++) {
7899 pw.print(" Process "); pw.print(procs.getKey());
7900 pw.print(" uid "); pw.print(uids.keyAt(i));
7901 pw.print(": last crashed ");
7902 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007903 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007904 }
7905 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007906 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007907
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007908 if (mBadProcesses.getMap().size() > 0) {
7909 if (needSep) pw.println(" ");
7910 needSep = true;
7911 pw.println(" Bad processes:");
7912 for (Map.Entry<String, SparseArray<Long>> procs
7913 : mBadProcesses.getMap().entrySet()) {
7914 SparseArray<Long> uids = procs.getValue();
7915 final int N = uids.size();
7916 for (int i=0; i<N; i++) {
7917 pw.print(" Bad process "); pw.print(procs.getKey());
7918 pw.print(" uid "); pw.print(uids.keyAt(i));
7919 pw.print(": crashed at time ");
7920 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007921 }
7922 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007924
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007925 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007926 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007927 if (mHeavyWeightProcess != null) {
7928 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7929 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007930 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007931 if (dumpAll) {
7932 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07007933 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07007934 pw.println(" mScreenCompatPackages:");
7935 for (Map.Entry<String, Integer> entry
7936 : mCompatModePackages.getPackages().entrySet()) {
7937 String pkg = entry.getKey();
7938 int mode = entry.getValue();
7939 pw.print(" "); pw.print(pkg); pw.print(": ");
7940 pw.print(mode); pw.println();
7941 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07007942 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007943 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007944 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7945 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7946 || mOrigWaitForDebugger) {
7947 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7948 + " mDebugTransient=" + mDebugTransient
7949 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7950 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07007951 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
7952 || mProfileFd != null) {
7953 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
7954 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
7955 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
7956 + mAutoStopProfiler);
7957 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007958 if (mAlwaysFinishActivities || mController != null) {
7959 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7960 + " mController=" + mController);
7961 }
7962 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007963 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007964 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007965 + " mProcessesReady=" + mProcessesReady
7966 + " mSystemReady=" + mSystemReady);
7967 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007968 + " mBooted=" + mBooted
7969 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007970 pw.print(" mLastPowerCheckRealtime=");
7971 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7972 pw.println("");
7973 pw.print(" mLastPowerCheckUptime=");
7974 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7975 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007976 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7977 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007978 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007979 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007980
7981 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007982 }
7983
Dianne Hackborn287952c2010-09-22 22:34:31 -07007984 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7985 int opti, boolean needSep, boolean dumpAll) {
7986 if (mProcessesToGc.size() > 0) {
7987 if (needSep) pw.println(" ");
7988 needSep = true;
7989 pw.println(" Processes that are waiting to GC:");
7990 long now = SystemClock.uptimeMillis();
7991 for (int i=0; i<mProcessesToGc.size(); i++) {
7992 ProcessRecord proc = mProcessesToGc.get(i);
7993 pw.print(" Process "); pw.println(proc);
7994 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7995 pw.print(", last gced=");
7996 pw.print(now-proc.lastRequestedGc);
7997 pw.print(" ms ago, last lowMem=");
7998 pw.print(now-proc.lastLowMemory);
7999 pw.println(" ms ago");
8000
8001 }
8002 }
8003 return needSep;
8004 }
8005
8006 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8007 int opti, boolean dumpAll) {
8008 boolean needSep = false;
8009
8010 if (mLruProcesses.size() > 0) {
8011 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8012
8013 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8014 @Override
8015 public int compare(ProcessRecord object1, ProcessRecord object2) {
8016 if (object1.setAdj != object2.setAdj) {
8017 return object1.setAdj > object2.setAdj ? -1 : 1;
8018 }
8019 if (object1.setSchedGroup != object2.setSchedGroup) {
8020 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8021 }
8022 if (object1.keeping != object2.keeping) {
8023 return object1.keeping ? -1 : 1;
8024 }
8025 if (object1.pid != object2.pid) {
8026 return object1.pid > object2.pid ? -1 : 1;
8027 }
8028 return 0;
8029 }
8030 };
8031
8032 Collections.sort(procs, comparator);
8033
8034 if (needSep) pw.println(" ");
8035 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008036 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008037 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8038 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
8039 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8040 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8041 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8042 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8043 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8044 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
8045 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8046 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8047 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008048
8049 if (needSep) pw.println(" ");
8050 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008051 pw.println(" Process OOM control:");
8052 dumpProcessOomList(pw, this, procs, " ",
8053 "Proc", "PERS", true);
8054 needSep = true;
8055 }
8056
8057 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8058
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008059 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008060 pw.println(" mHomeProcess: " + mHomeProcess);
8061 if (mHeavyWeightProcess != null) {
8062 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8063 }
8064
8065 return true;
8066 }
8067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008068 /**
8069 * There are three ways to call this:
8070 * - no service specified: dump all the services
8071 * - a flattened component name that matched an existing service was specified as the
8072 * first arg: dump that one service
8073 * - the first arg isn't the flattened component name of an existing service:
8074 * dump all services whose component contains the first arg as a substring
8075 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008076 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8077 int opti, boolean dumpAll) {
8078 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008079
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008080 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008081 synchronized (this) {
8082 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008083 services.add(r1);
8084 }
8085 }
8086 } else {
8087 ComponentName componentName = name != null
8088 ? ComponentName.unflattenFromString(name) : null;
8089 int objectId = 0;
8090 if (componentName == null) {
8091 // Not a '/' separated full component name; maybe an object ID?
8092 try {
8093 objectId = Integer.parseInt(name, 16);
8094 name = null;
8095 componentName = null;
8096 } catch (RuntimeException e) {
8097 }
8098 }
8099
8100 synchronized (this) {
8101 for (ServiceRecord r1 : mServices.values()) {
8102 if (componentName != null) {
8103 if (r1.name.equals(componentName)) {
8104 services.add(r1);
8105 }
8106 } else if (name != null) {
8107 if (r1.name.flattenToString().contains(name)) {
8108 services.add(r1);
8109 }
8110 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008111 services.add(r1);
8112 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008113 }
8114 }
8115 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008116
8117 if (services.size() <= 0) {
8118 return false;
8119 }
8120
8121 boolean needSep = false;
8122 for (int i=0; i<services.size(); i++) {
8123 if (needSep) {
8124 pw.println();
8125 }
8126 needSep = true;
8127 dumpService("", fd, pw, services.get(i), args, dumpAll);
8128 }
8129 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008130 }
8131
8132 /**
8133 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8134 * there is a thread associated with the service.
8135 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008136 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8137 final ServiceRecord r, String[] args, boolean dumpAll) {
8138 String innerPrefix = prefix + " ";
8139 synchronized (this) {
8140 pw.print(prefix); pw.print("SERVICE ");
8141 pw.print(r.shortName); pw.print(" ");
8142 pw.print(Integer.toHexString(System.identityHashCode(r)));
8143 pw.print(" pid=");
8144 if (r.app != null) pw.println(r.app.pid);
8145 else pw.println("(not running)");
8146 if (dumpAll) {
8147 r.dump(pw, innerPrefix);
8148 }
8149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008151 pw.print(prefix); pw.println(" Client:");
8152 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008153 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008154 TransferPipe tp = new TransferPipe();
8155 try {
8156 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8157 tp.setBufferPrefix(prefix + " ");
8158 tp.go(fd);
8159 } finally {
8160 tp.kill();
8161 }
8162 } catch (IOException e) {
8163 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008164 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008165 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008166 }
8167 }
8168 }
8169
Dianne Hackborn625ac272010-09-17 18:29:22 -07008170 /**
8171 * There are three things that cmd can be:
8172 * - a flattened component name that matched an existing activity
8173 * - the cmd arg isn't the flattened component name of an existing activity:
8174 * dump all activity whose component contains the cmd as a substring
8175 * - A hex number of the ActivityRecord object instance.
8176 */
8177 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8178 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008179 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008180
8181 if ("all".equals(name)) {
8182 synchronized (this) {
8183 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008184 activities.add(r1);
8185 }
8186 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008187 } else if ("top".equals(name)) {
8188 synchronized (this) {
8189 final int N = mMainStack.mHistory.size();
8190 if (N > 0) {
8191 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8192 }
8193 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008194 } else {
8195 ComponentName componentName = ComponentName.unflattenFromString(name);
8196 int objectId = 0;
8197 if (componentName == null) {
8198 // Not a '/' separated full component name; maybe an object ID?
8199 try {
8200 objectId = Integer.parseInt(name, 16);
8201 name = null;
8202 componentName = null;
8203 } catch (RuntimeException e) {
8204 }
8205 }
8206
8207 synchronized (this) {
8208 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8209 if (componentName != null) {
8210 if (r1.intent.getComponent().equals(componentName)) {
8211 activities.add(r1);
8212 }
8213 } else if (name != null) {
8214 if (r1.intent.getComponent().flattenToString().contains(name)) {
8215 activities.add(r1);
8216 }
8217 } else if (System.identityHashCode(r1) == objectId) {
8218 activities.add(r1);
8219 }
8220 }
8221 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008222 }
8223
8224 if (activities.size() <= 0) {
8225 return false;
8226 }
8227
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008228 String[] newArgs = new String[args.length - opti];
8229 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8230
Dianne Hackborn30d71892010-12-11 10:37:55 -08008231 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008232 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008233 for (int i=activities.size()-1; i>=0; i--) {
8234 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008235 if (needSep) {
8236 pw.println();
8237 }
8238 needSep = true;
8239 synchronized (this) {
8240 if (lastTask != r.task) {
8241 lastTask = r.task;
8242 pw.print("TASK "); pw.print(lastTask.affinity);
8243 pw.print(" id="); pw.println(lastTask.taskId);
8244 if (dumpAll) {
8245 lastTask.dump(pw, " ");
8246 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008247 }
8248 }
8249 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008250 }
8251 return true;
8252 }
8253
8254 /**
8255 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8256 * there is a thread associated with the activity.
8257 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008258 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008259 final ActivityRecord r, String[] args, boolean dumpAll) {
8260 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008261 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008262 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8263 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8264 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008265 if (r.app != null) pw.println(r.app.pid);
8266 else pw.println("(not running)");
8267 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008268 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008269 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008270 }
8271 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008272 // flush anything that is already in the PrintWriter since the thread is going
8273 // to write to the file descriptor directly
8274 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008275 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008276 TransferPipe tp = new TransferPipe();
8277 try {
8278 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8279 innerPrefix, args);
8280 tp.go(fd);
8281 } finally {
8282 tp.kill();
8283 }
8284 } catch (IOException e) {
8285 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008286 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008287 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008288 }
8289 }
8290 }
8291
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008292 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8293 int opti, boolean dumpAll) {
8294 boolean needSep = false;
8295
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008296 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008297 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008298 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008299 pw.println(" Registered Receivers:");
8300 Iterator it = mRegisteredReceivers.values().iterator();
8301 while (it.hasNext()) {
8302 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008303 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008304 r.dump(pw, " ");
8305 }
8306 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008307
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008308 pw.println();
8309 pw.println(" Receiver Resolver Table:");
8310 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008311 needSep = true;
8312 }
8313
8314 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8315 || mPendingBroadcast != null) {
8316 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008317 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008318 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008319 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008320 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8321 pw.println(" Broadcast #" + i + ":");
8322 mParallelBroadcasts.get(i).dump(pw, " ");
8323 }
8324 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008325 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008326 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008327 }
8328 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8329 pw.println(" Serialized Broadcast #" + i + ":");
8330 mOrderedBroadcasts.get(i).dump(pw, " ");
8331 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008332 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008333 pw.println(" Pending broadcast:");
8334 if (mPendingBroadcast != null) {
8335 mPendingBroadcast.dump(pw, " ");
8336 } else {
8337 pw.println(" (null)");
8338 }
8339 needSep = true;
8340 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008341
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008342 if (needSep) {
8343 pw.println();
8344 }
8345 pw.println(" Historical broadcasts:");
8346 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8347 BroadcastRecord r = mBroadcastHistory[i];
8348 if (r == null) {
8349 break;
8350 }
8351 if (dumpAll) {
8352 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8353 r.dump(pw, " ");
8354 } else {
8355 if (i >= 50) {
8356 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008357 break;
8358 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008359 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008360 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008361 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008362 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008363
8364 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008365 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008366 pw.println(" Sticky broadcasts:");
8367 StringBuilder sb = new StringBuilder(128);
8368 for (Map.Entry<String, ArrayList<Intent>> ent
8369 : mStickyBroadcasts.entrySet()) {
8370 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008371 if (dumpAll) {
8372 pw.println(":");
8373 ArrayList<Intent> intents = ent.getValue();
8374 final int N = intents.size();
8375 for (int i=0; i<N; i++) {
8376 sb.setLength(0);
8377 sb.append(" Intent: ");
8378 intents.get(i).toShortString(sb, true, false);
8379 pw.println(sb.toString());
8380 Bundle bundle = intents.get(i).getExtras();
8381 if (bundle != null) {
8382 pw.print(" ");
8383 pw.println(bundle.toString());
8384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008385 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008386 } else {
8387 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008388 }
8389 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008390 needSep = true;
8391 }
8392
8393 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008394 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008395 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008396 pw.println(" mHandler:");
8397 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008398 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008399 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008400
8401 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008402 }
8403
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008404 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008405 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008406 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008407
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008408 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8409 if (mServices.size() > 0) {
8410 pw.println(" Active services:");
8411 long nowReal = SystemClock.elapsedRealtime();
8412 Iterator<ServiceRecord> it = mServices.values().iterator();
8413 needSep = false;
8414 while (it.hasNext()) {
8415 ServiceRecord r = it.next();
8416 if (needSep) {
8417 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008418 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008419 pw.print(" * "); pw.println(r);
8420 if (dumpAll) {
8421 r.dump(pw, " ");
8422 needSep = true;
8423 } else {
8424 pw.print(" app="); pw.println(r.app);
8425 pw.print(" created=");
8426 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8427 pw.print(" started="); pw.print(r.startRequested);
8428 pw.print(" connections="); pw.println(r.connections.size());
8429 }
8430 if (dumpClient && r.app != null && r.app.thread != null) {
8431 pw.println(" Client:");
8432 pw.flush();
8433 try {
8434 TransferPipe tp = new TransferPipe();
8435 try {
8436 r.app.thread.dumpService(
8437 tp.getWriteFd().getFileDescriptor(), r, args);
8438 tp.setBufferPrefix(" ");
8439 // Short timeout, since blocking here can
8440 // deadlock with the application.
8441 tp.go(fd, 2000);
8442 } finally {
8443 tp.kill();
8444 }
8445 } catch (IOException e) {
8446 pw.println(" Failure while dumping the service: " + e);
8447 } catch (RemoteException e) {
8448 pw.println(" Got a RemoteException while dumping the service");
8449 }
8450 needSep = true;
8451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008452 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008453 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008455
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008456 if (mPendingServices.size() > 0) {
8457 if (needSep) pw.println(" ");
8458 pw.println(" Pending services:");
8459 for (int i=0; i<mPendingServices.size(); i++) {
8460 ServiceRecord r = mPendingServices.get(i);
8461 pw.print(" * Pending "); pw.println(r);
8462 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008463 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008464 needSep = true;
8465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008466
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008467 if (mRestartingServices.size() > 0) {
8468 if (needSep) pw.println(" ");
8469 pw.println(" Restarting services:");
8470 for (int i=0; i<mRestartingServices.size(); i++) {
8471 ServiceRecord r = mRestartingServices.get(i);
8472 pw.print(" * Restarting "); pw.println(r);
8473 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008474 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008475 needSep = true;
8476 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008477
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008478 if (mStoppingServices.size() > 0) {
8479 if (needSep) pw.println(" ");
8480 pw.println(" Stopping services:");
8481 for (int i=0; i<mStoppingServices.size(); i++) {
8482 ServiceRecord r = mStoppingServices.get(i);
8483 pw.print(" * Stopping "); pw.println(r);
8484 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008485 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008486 needSep = true;
8487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008488
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008489 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008490 if (mServiceConnections.size() > 0) {
8491 if (needSep) pw.println(" ");
8492 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008493 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008494 = mServiceConnections.values().iterator();
8495 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008496 ArrayList<ConnectionRecord> r = it.next();
8497 for (int i=0; i<r.size(); i++) {
8498 pw.print(" * "); pw.println(r.get(i));
8499 r.get(i).dump(pw, " ");
8500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008501 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008502 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008503 }
8504 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008505
8506 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008507 }
8508
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008509 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8510 int opti, boolean dumpAll) {
8511 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008512
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008513 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8514 if (mProvidersByClass.size() > 0) {
8515 if (needSep) pw.println(" ");
8516 pw.println(" Published content providers (by class):");
8517 Iterator<Map.Entry<String, ContentProviderRecord>> it
8518 = mProvidersByClass.entrySet().iterator();
8519 while (it.hasNext()) {
8520 Map.Entry<String, ContentProviderRecord> e = it.next();
8521 ContentProviderRecord r = e.getValue();
8522 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008523 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008524 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008525 } else {
8526 pw.print(" * "); pw.print(r.name.toShortString());
8527 if (r.app != null) {
8528 pw.println(":");
8529 pw.print(" "); pw.println(r.app);
8530 } else {
8531 pw.println();
8532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008534 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008535 needSep = true;
8536 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008537
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008538 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008539 if (mProvidersByName.size() > 0) {
8540 pw.println(" ");
8541 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008542 Iterator<Map.Entry<String, ContentProviderRecord>> it
8543 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008544 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008545 Map.Entry<String, ContentProviderRecord> e = it.next();
8546 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008547 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8548 pw.println(r);
8549 }
8550 needSep = true;
8551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008552 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008553
8554 if (mLaunchingProviders.size() > 0) {
8555 if (needSep) pw.println(" ");
8556 pw.println(" Launching content providers:");
8557 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8558 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8559 pw.println(mLaunchingProviders.get(i));
8560 }
8561 needSep = true;
8562 }
8563
8564 if (mGrantedUriPermissions.size() > 0) {
8565 pw.println();
8566 pw.println("Granted Uri Permissions:");
8567 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8568 int uid = mGrantedUriPermissions.keyAt(i);
8569 HashMap<Uri, UriPermission> perms
8570 = mGrantedUriPermissions.valueAt(i);
8571 pw.print(" * UID "); pw.print(uid);
8572 pw.println(" holds:");
8573 for (UriPermission perm : perms.values()) {
8574 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008575 if (dumpAll) {
8576 perm.dump(pw, " ");
8577 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008578 }
8579 }
8580 needSep = true;
8581 }
8582
8583 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008584 }
8585
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008586 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8587 int opti, boolean dumpAll) {
8588 boolean needSep = false;
8589
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008590 if (this.mIntentSenderRecords.size() > 0) {
8591 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8592 Iterator<WeakReference<PendingIntentRecord>> it
8593 = mIntentSenderRecords.values().iterator();
8594 while (it.hasNext()) {
8595 WeakReference<PendingIntentRecord> ref = it.next();
8596 PendingIntentRecord rec = ref != null ? ref.get(): null;
8597 needSep = true;
8598 if (rec != null) {
8599 pw.print(" * "); pw.println(rec);
8600 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008601 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008602 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008603 } else {
8604 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008605 }
8606 }
8607 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008608
8609 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008610 }
8611
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008612 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8613 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008614 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008615 boolean needNL = false;
8616 final String innerPrefix = prefix + " ";
8617 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008618 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008619 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008620 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008621 if (needNL) {
8622 pw.println(" ");
8623 needNL = false;
8624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008625 if (lastTask != r.task) {
8626 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008627 pw.print(prefix);
8628 pw.print(full ? "* " : " ");
8629 pw.println(lastTask);
8630 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008631 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008632 } else if (complete) {
8633 // Complete + brief == give a summary. Isn't that obvious?!?
8634 if (lastTask.intent != null) {
8635 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8636 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008638 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008639 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8640 pw.print(" #"); pw.print(i); pw.print(": ");
8641 pw.println(r);
8642 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008643 r.dump(pw, innerPrefix);
8644 } else if (complete) {
8645 // Complete + brief == give a summary. Isn't that obvious?!?
8646 pw.print(innerPrefix); pw.println(r.intent);
8647 if (r.app != null) {
8648 pw.print(innerPrefix); pw.println(r.app);
8649 }
8650 }
8651 if (client && r.app != null && r.app.thread != null) {
8652 // flush anything that is already in the PrintWriter since the thread is going
8653 // to write to the file descriptor directly
8654 pw.flush();
8655 try {
8656 TransferPipe tp = new TransferPipe();
8657 try {
8658 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8659 innerPrefix, args);
8660 // Short timeout, since blocking here can
8661 // deadlock with the application.
8662 tp.go(fd, 2000);
8663 } finally {
8664 tp.kill();
8665 }
8666 } catch (IOException e) {
8667 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8668 } catch (RemoteException e) {
8669 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8670 }
8671 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008672 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008673 }
8674 }
8675
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008676 private static String buildOomTag(String prefix, String space, int val, int base) {
8677 if (val == base) {
8678 if (space == null) return prefix;
8679 return prefix + " ";
8680 }
8681 return prefix + "+" + Integer.toString(val-base);
8682 }
8683
8684 private static final int dumpProcessList(PrintWriter pw,
8685 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008686 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008687 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008688 final int N = list.size()-1;
8689 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008690 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008691 pw.println(String.format("%s%s #%2d: %s",
8692 prefix, (r.persistent ? persistentLabel : normalLabel),
8693 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008694 if (r.persistent) {
8695 numPers++;
8696 }
8697 }
8698 return numPers;
8699 }
8700
Dianne Hackborn287952c2010-09-22 22:34:31 -07008701 private static final void dumpProcessOomList(PrintWriter pw,
8702 ActivityManagerService service, List<ProcessRecord> list,
8703 String prefix, String normalLabel, String persistentLabel,
8704 boolean inclDetails) {
8705
8706 final long curRealtime = SystemClock.elapsedRealtime();
8707 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8708 final long curUptime = SystemClock.uptimeMillis();
8709 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8710
8711 final int N = list.size()-1;
8712 for (int i=N; i>=0; i--) {
8713 ProcessRecord r = list.get(i);
8714 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008715 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8716 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8717 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8718 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
8719 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
8720 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
8721 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
8722 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
8723 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
8724 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
8725 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8726 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
8727 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8728 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
8729 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
8730 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
8731 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
8732 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
8733 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
8734 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
8735 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
8736 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008737 } else {
8738 oomAdj = Integer.toString(r.setAdj);
8739 }
8740 String schedGroup;
8741 switch (r.setSchedGroup) {
8742 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8743 schedGroup = "B";
8744 break;
8745 case Process.THREAD_GROUP_DEFAULT:
8746 schedGroup = "F";
8747 break;
8748 default:
8749 schedGroup = Integer.toString(r.setSchedGroup);
8750 break;
8751 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008752 String foreground;
8753 if (r.foregroundActivities) {
8754 foreground = "A";
8755 } else if (r.foregroundServices) {
8756 foreground = "S";
8757 } else {
8758 foreground = " ";
8759 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008760 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008761 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008762 N-i, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
8763 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008764 if (r.adjSource != null || r.adjTarget != null) {
8765 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008766 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008767 if (r.adjTarget instanceof ComponentName) {
8768 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8769 } else if (r.adjTarget != null) {
8770 pw.print(r.adjTarget.toString());
8771 } else {
8772 pw.print("{null}");
8773 }
8774 pw.print("<=");
8775 if (r.adjSource instanceof ProcessRecord) {
8776 pw.print("Proc{");
8777 pw.print(((ProcessRecord)r.adjSource).toShortString());
8778 pw.println("}");
8779 } else if (r.adjSource != null) {
8780 pw.println(r.adjSource.toString());
8781 } else {
8782 pw.println("{null}");
8783 }
8784 }
8785 if (inclDetails) {
8786 pw.print(prefix);
8787 pw.print(" ");
8788 pw.print("oom: max="); pw.print(r.maxAdj);
8789 pw.print(" hidden="); pw.print(r.hiddenAdj);
8790 pw.print(" curRaw="); pw.print(r.curRawAdj);
8791 pw.print(" setRaw="); pw.print(r.setRawAdj);
8792 pw.print(" cur="); pw.print(r.curAdj);
8793 pw.print(" set="); pw.println(r.setAdj);
8794 pw.print(prefix);
8795 pw.print(" ");
8796 pw.print("keeping="); pw.print(r.keeping);
8797 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008798 pw.print(" empty="); pw.print(r.empty);
8799 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008800
8801 if (!r.keeping) {
8802 if (r.lastWakeTime != 0) {
8803 long wtime;
8804 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8805 synchronized (stats) {
8806 wtime = stats.getProcessWakeTime(r.info.uid,
8807 r.pid, curRealtime);
8808 }
8809 long timeUsed = wtime - r.lastWakeTime;
8810 pw.print(prefix);
8811 pw.print(" ");
8812 pw.print("keep awake over ");
8813 TimeUtils.formatDuration(realtimeSince, pw);
8814 pw.print(" used ");
8815 TimeUtils.formatDuration(timeUsed, pw);
8816 pw.print(" (");
8817 pw.print((timeUsed*100)/realtimeSince);
8818 pw.println("%)");
8819 }
8820 if (r.lastCpuTime != 0) {
8821 long timeUsed = r.curCpuTime - r.lastCpuTime;
8822 pw.print(prefix);
8823 pw.print(" ");
8824 pw.print("run cpu over ");
8825 TimeUtils.formatDuration(uptimeSince, pw);
8826 pw.print(" used ");
8827 TimeUtils.formatDuration(timeUsed, pw);
8828 pw.print(" (");
8829 pw.print((timeUsed*100)/uptimeSince);
8830 pw.println("%)");
8831 }
8832 }
8833 }
8834 }
8835 }
8836
Dianne Hackbornb437e092011-08-05 17:50:29 -07008837 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008838 ArrayList<ProcessRecord> procs;
8839 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008840 if (args != null && args.length > start
8841 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008842 procs = new ArrayList<ProcessRecord>();
8843 int pid = -1;
8844 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008845 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008846 } catch (NumberFormatException e) {
8847
8848 }
8849 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8850 ProcessRecord proc = mLruProcesses.get(i);
8851 if (proc.pid == pid) {
8852 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07008853 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008854 procs.add(proc);
8855 }
8856 }
8857 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008858 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008859 return null;
8860 }
8861 } else {
8862 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8863 }
8864 }
8865 return procs;
8866 }
8867
8868 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8869 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008870 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008871 if (procs == null) {
8872 return;
8873 }
8874
8875 long uptime = SystemClock.uptimeMillis();
8876 long realtime = SystemClock.elapsedRealtime();
8877 pw.println("Applications Graphics Acceleration Info:");
8878 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8879
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008880 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8881 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008882 if (r.thread != null) {
8883 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8884 pw.flush();
8885 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008886 TransferPipe tp = new TransferPipe();
8887 try {
8888 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
8889 tp.go(fd);
8890 } finally {
8891 tp.kill();
8892 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008893 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008894 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008895 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07008896 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008897 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008898 pw.flush();
8899 }
8900 }
8901 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07008902 }
8903
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008904 final static class MemItem {
8905 final String label;
8906 final long pss;
8907
8908 public MemItem(String _label, long _pss) {
8909 label = _label;
8910 pss = _pss;
8911 }
8912 }
8913
Dianne Hackbornb437e092011-08-05 17:50:29 -07008914 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
8915 boolean sort) {
8916 if (sort) {
8917 Collections.sort(items, new Comparator<MemItem>() {
8918 @Override
8919 public int compare(MemItem lhs, MemItem rhs) {
8920 if (lhs.pss < rhs.pss) {
8921 return 1;
8922 } else if (lhs.pss > rhs.pss) {
8923 return -1;
8924 }
8925 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008926 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07008927 });
8928 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008929
8930 for (int i=0; i<items.size(); i++) {
8931 MemItem mi = items.get(i);
8932 pw.print(prefix); pw.printf("%8d Kb: ", mi.pss); pw.println(mi.label);
8933 }
8934 }
8935
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008936 final void dumpApplicationMemoryUsage(FileDescriptor fd,
8937 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008938 boolean dumpAll = false;
8939
8940 int opti = 0;
8941 while (opti < args.length) {
8942 String opt = args[opti];
8943 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8944 break;
8945 }
8946 opti++;
8947 if ("-a".equals(opt)) {
8948 dumpAll = true;
8949 } else if ("-h".equals(opt)) {
8950 pw.println("meminfo dump options: [-a] [process]");
8951 pw.println(" -a: include all available information for each process.");
8952 pw.println("If [process] is specified it can be the name or ");
8953 pw.println("pid of a specific process to dump.");
8954 return;
8955 } else {
8956 pw.println("Unknown argument: " + opt + "; use -h for help");
8957 }
8958 }
8959
8960 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008961 if (procs == null) {
8962 return;
8963 }
8964
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008965 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008966 long uptime = SystemClock.uptimeMillis();
8967 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07008968
8969 if (procs.size() == 1 || isCheckinRequest) {
8970 dumpAll = true;
8971 }
8972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008973 if (isCheckinRequest) {
8974 // short checkin version
8975 pw.println(uptime + "," + realtime);
8976 pw.flush();
8977 } else {
8978 pw.println("Applications Memory Usage (kB):");
8979 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8980 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008981
Dianne Hackbornb437e092011-08-05 17:50:29 -07008982 String[] innerArgs = new String[args.length-opti];
8983 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
8984
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008985 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
8986 long nativePss=0, dalvikPss=0, otherPss=0;
8987 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
8988
Dianne Hackbornb437e092011-08-05 17:50:29 -07008989 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07008990 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
8991 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
8992 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07008993 };
8994 final String[] oomLabel = new String[] {
8995 "System", "Persistent", "Foreground",
8996 "Visible", "Perceptible", "Heavy Weight",
8997 "Backup", "Services", "Home", "Background"
8998 };
8999 long oomPss[] = new long[oomLabel.length];
9000
9001 long totalPss = 0;
9002
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009003 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9004 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009005 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009006 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009007 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9008 pw.flush();
9009 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009010 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009011 if (dumpAll) {
9012 try {
9013 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9014 } catch (RemoteException e) {
9015 if (!isCheckinRequest) {
9016 pw.println("Got RemoteException!");
9017 pw.flush();
9018 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009019 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009020 } else {
9021 mi = new Debug.MemoryInfo();
9022 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009023 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009024
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009025 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009026 long myTotalPss = mi.getTotalPss();
9027 totalPss += myTotalPss;
9028 procMems.add(new MemItem(r.processName + " (pid " + r.pid + ")", myTotalPss));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009029
9030 nativePss += mi.nativePss;
9031 dalvikPss += mi.dalvikPss;
9032 otherPss += mi.otherPss;
9033 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9034 long mem = mi.getOtherPss(j);
9035 miscPss[j] += mem;
9036 otherPss -= mem;
9037 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009038
9039 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9040 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9041 oomPss[oomIndex] += myTotalPss;
9042 break;
9043 }
9044 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009045 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009046 }
9047 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009048
9049 if (!isCheckinRequest && procs.size() > 1) {
9050 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9051
9052 catMems.add(new MemItem("Native", nativePss));
9053 catMems.add(new MemItem("Dalvik", dalvikPss));
9054 catMems.add(new MemItem("Unknown", otherPss));
9055 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9056 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9057 }
9058
Dianne Hackbornb437e092011-08-05 17:50:29 -07009059 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9060 for (int j=0; j<oomPss.length; j++) {
9061 if (oomPss[j] != 0) {
9062 oomMems.add(new MemItem(oomLabel[j], oomPss[j]));
9063 }
9064 }
9065
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009066 pw.println();
9067 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009068 dumpMemItems(pw, " ", procMems, true);
9069 pw.println();
9070 pw.println("Total PSS by OOM adjustment:");
9071 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009072 pw.println();
9073 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009074 dumpMemItems(pw, " ", catMems, true);
9075 pw.println();
9076 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009077 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009078 }
9079
9080 /**
9081 * Searches array of arguments for the specified string
9082 * @param args array of argument strings
9083 * @param value value to search for
9084 * @return true if the value is contained in the array
9085 */
9086 private static boolean scanArgs(String[] args, String value) {
9087 if (args != null) {
9088 for (String arg : args) {
9089 if (value.equals(arg)) {
9090 return true;
9091 }
9092 }
9093 }
9094 return false;
9095 }
9096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009097 private final void killServicesLocked(ProcessRecord app,
9098 boolean allowRestart) {
9099 // Report disconnected services.
9100 if (false) {
9101 // XXX we are letting the client link to the service for
9102 // death notifications.
9103 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009104 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009105 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009106 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009107 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009108 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009109 = r.connections.values().iterator();
9110 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009111 ArrayList<ConnectionRecord> cl = jt.next();
9112 for (int i=0; i<cl.size(); i++) {
9113 ConnectionRecord c = cl.get(i);
9114 if (c.binding.client != app) {
9115 try {
9116 //c.conn.connected(r.className, null);
9117 } catch (Exception e) {
9118 // todo: this should be asynchronous!
9119 Slog.w(TAG, "Exception thrown disconnected servce "
9120 + r.shortName
9121 + " from app " + app.processName, e);
9122 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009123 }
9124 }
9125 }
9126 }
9127 }
9128 }
9129 }
9130
9131 // Clean up any connections this application has to other services.
9132 if (app.connections.size() > 0) {
9133 Iterator<ConnectionRecord> it = app.connections.iterator();
9134 while (it.hasNext()) {
9135 ConnectionRecord r = it.next();
9136 removeConnectionLocked(r, app, null);
9137 }
9138 }
9139 app.connections.clear();
9140
9141 if (app.services.size() != 0) {
9142 // Any services running in the application need to be placed
9143 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009144 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009145 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009146 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009147 synchronized (sr.stats.getBatteryStats()) {
9148 sr.stats.stopLaunchedLocked();
9149 }
9150 sr.app = null;
9151 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009152 if (mStoppingServices.remove(sr)) {
9153 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9154 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009155
9156 boolean hasClients = sr.bindings.size() > 0;
9157 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009158 Iterator<IntentBindRecord> bindings
9159 = sr.bindings.values().iterator();
9160 while (bindings.hasNext()) {
9161 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009162 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009163 + ": shouldUnbind=" + b.hasBound);
9164 b.binder = null;
9165 b.requested = b.received = b.hasBound = false;
9166 }
9167 }
9168
Dianne Hackborn070783f2010-12-29 16:46:28 -08009169 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9170 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009171 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009172 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009173 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009174 sr.crashCount, sr.shortName, app.pid);
9175 bringDownServiceLocked(sr, true);
9176 } else if (!allowRestart) {
9177 bringDownServiceLocked(sr, true);
9178 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009179 boolean canceled = scheduleServiceRestartLocked(sr, true);
9180
9181 // Should the service remain running? Note that in the
9182 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009183 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009184 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9185 if (sr.pendingStarts.size() == 0) {
9186 sr.startRequested = false;
9187 if (!hasClients) {
9188 // Whoops, no reason to restart!
9189 bringDownServiceLocked(sr, true);
9190 }
9191 }
9192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009193 }
9194 }
9195
9196 if (!allowRestart) {
9197 app.services.clear();
9198 }
9199 }
9200
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009201 // Make sure we have no more records on the stopping list.
9202 int i = mStoppingServices.size();
9203 while (i > 0) {
9204 i--;
9205 ServiceRecord sr = mStoppingServices.get(i);
9206 if (sr.app == app) {
9207 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009208 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009209 }
9210 }
9211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009212 app.executingServices.clear();
9213 }
9214
9215 private final void removeDyingProviderLocked(ProcessRecord proc,
9216 ContentProviderRecord cpr) {
9217 synchronized (cpr) {
9218 cpr.launchingApp = null;
9219 cpr.notifyAll();
9220 }
9221
9222 mProvidersByClass.remove(cpr.info.name);
9223 String names[] = cpr.info.authority.split(";");
9224 for (int j = 0; j < names.length; j++) {
9225 mProvidersByName.remove(names[j]);
9226 }
9227
9228 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9229 while (cit.hasNext()) {
9230 ProcessRecord capp = cit.next();
9231 if (!capp.persistent && capp.thread != null
9232 && capp.pid != 0
9233 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009234 Slog.i(TAG, "Kill " + capp.processName
9235 + " (pid " + capp.pid + "): provider " + cpr.info.name
9236 + " in dying process " + proc.processName);
9237 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9238 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009239 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009240 }
9241 }
9242
9243 mLaunchingProviders.remove(cpr);
9244 }
9245
9246 /**
9247 * Main code for cleaning up a process when it has gone away. This is
9248 * called both as a result of the process dying, or directly when stopping
9249 * a process when running in single process mode.
9250 */
9251 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009252 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009253 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009254 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009255 }
9256
Dianne Hackborn36124872009-10-08 16:22:03 -07009257 mProcessesToGc.remove(app);
9258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009259 // Dismiss any open dialogs.
9260 if (app.crashDialog != null) {
9261 app.crashDialog.dismiss();
9262 app.crashDialog = null;
9263 }
9264 if (app.anrDialog != null) {
9265 app.anrDialog.dismiss();
9266 app.anrDialog = null;
9267 }
9268 if (app.waitDialog != null) {
9269 app.waitDialog.dismiss();
9270 app.waitDialog = null;
9271 }
9272
9273 app.crashing = false;
9274 app.notResponding = false;
9275
9276 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009277 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009278 app.thread = null;
9279 app.forcingToForeground = null;
9280 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009281 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009282 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009283 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009284
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009285 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009286
9287 boolean restart = false;
9288
9289 int NL = mLaunchingProviders.size();
9290
9291 // Remove published content providers.
9292 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009293 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009294 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009295 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009296 cpr.provider = null;
9297 cpr.app = null;
9298
9299 // See if someone is waiting for this provider... in which
9300 // case we don't remove it, but just let it restart.
9301 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009302 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009303 for (; i<NL; i++) {
9304 if (mLaunchingProviders.get(i) == cpr) {
9305 restart = true;
9306 break;
9307 }
9308 }
9309 } else {
9310 i = NL;
9311 }
9312
9313 if (i >= NL) {
9314 removeDyingProviderLocked(app, cpr);
9315 NL = mLaunchingProviders.size();
9316 }
9317 }
9318 app.pubProviders.clear();
9319 }
9320
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009321 // Take care of any launching providers waiting for this process.
9322 if (checkAppInLaunchingProvidersLocked(app, false)) {
9323 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009324 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009326 // Unregister from connected content providers.
9327 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009328 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009329 while (it.hasNext()) {
9330 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9331 cpr.clients.remove(app);
9332 }
9333 app.conProviders.clear();
9334 }
9335
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009336 // At this point there may be remaining entries in mLaunchingProviders
9337 // where we were the only one waiting, so they are no longer of use.
9338 // Look for these and clean up if found.
9339 // XXX Commented out for now. Trying to figure out a way to reproduce
9340 // the actual situation to identify what is actually going on.
9341 if (false) {
9342 for (int i=0; i<NL; i++) {
9343 ContentProviderRecord cpr = (ContentProviderRecord)
9344 mLaunchingProviders.get(i);
9345 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9346 synchronized (cpr) {
9347 cpr.launchingApp = null;
9348 cpr.notifyAll();
9349 }
9350 }
9351 }
9352 }
9353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009354 skipCurrentReceiverLocked(app);
9355
9356 // Unregister any receivers.
9357 if (app.receivers.size() > 0) {
9358 Iterator<ReceiverList> it = app.receivers.iterator();
9359 while (it.hasNext()) {
9360 removeReceiverLocked(it.next());
9361 }
9362 app.receivers.clear();
9363 }
9364
Christopher Tate181fafa2009-05-14 11:12:14 -07009365 // If the app is undergoing backup, tell the backup manager about it
9366 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009367 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009368 try {
9369 IBackupManager bm = IBackupManager.Stub.asInterface(
9370 ServiceManager.getService(Context.BACKUP_SERVICE));
9371 bm.agentDisconnected(app.info.packageName);
9372 } catch (RemoteException e) {
9373 // can't happen; backup manager is local
9374 }
9375 }
9376
Jeff Sharkey287bd832011-05-28 19:36:26 -07009377 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009379 // If the caller is restarting this app, then leave it in its
9380 // current lists and let the caller take care of it.
9381 if (restarting) {
9382 return;
9383 }
9384
9385 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009386 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009387 "Removing non-persistent process during cleanup: " + app);
9388 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009389 if (mHeavyWeightProcess == app) {
9390 mHeavyWeightProcess = null;
9391 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009393 } else if (!app.removed) {
9394 // This app is persistent, so we need to keep its record around.
9395 // If it is not already on the pending app list, add it there
9396 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009397 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9398 mPersistentStartingProcesses.add(app);
9399 restart = true;
9400 }
9401 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009402 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9403 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009404 mProcessesOnHold.remove(app);
9405
The Android Open Source Project4df24232009-03-05 14:34:35 -08009406 if (app == mHomeProcess) {
9407 mHomeProcess = null;
9408 }
9409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009410 if (restart) {
9411 // We have components that still need to be running in the
9412 // process, so re-launch it.
9413 mProcessNames.put(app.processName, app.info.uid, app);
9414 startProcessLocked(app, "restart", app.processName);
9415 } else if (app.pid > 0 && app.pid != MY_PID) {
9416 // Goodbye!
9417 synchronized (mPidsSelfLocked) {
9418 mPidsSelfLocked.remove(app.pid);
9419 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9420 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009421 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009422 }
9423 }
9424
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009425 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9426 // Look through the content providers we are waiting to have launched,
9427 // and if any run in this process then either schedule a restart of
9428 // the process or kill the client waiting for it if this process has
9429 // gone bad.
9430 int NL = mLaunchingProviders.size();
9431 boolean restart = false;
9432 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009433 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009434 if (cpr.launchingApp == app) {
9435 if (!alwaysBad && !app.bad) {
9436 restart = true;
9437 } else {
9438 removeDyingProviderLocked(app, cpr);
9439 NL = mLaunchingProviders.size();
9440 }
9441 }
9442 }
9443 return restart;
9444 }
9445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009446 // =========================================================
9447 // SERVICES
9448 // =========================================================
9449
9450 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9451 ActivityManager.RunningServiceInfo info =
9452 new ActivityManager.RunningServiceInfo();
9453 info.service = r.name;
9454 if (r.app != null) {
9455 info.pid = r.app.pid;
9456 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009457 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009458 info.process = r.processName;
9459 info.foreground = r.isForeground;
9460 info.activeSince = r.createTime;
9461 info.started = r.startRequested;
9462 info.clientCount = r.connections.size();
9463 info.crashCount = r.crashCount;
9464 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009465 if (r.isForeground) {
9466 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9467 }
9468 if (r.startRequested) {
9469 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9470 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009471 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009472 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9473 }
9474 if (r.app != null && r.app.persistent) {
9475 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9476 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009477
9478 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9479 for (int i=0; i<connl.size(); i++) {
9480 ConnectionRecord conn = connl.get(i);
9481 if (conn.clientLabel != 0) {
9482 info.clientPackage = conn.binding.client.info.packageName;
9483 info.clientLabel = conn.clientLabel;
9484 return info;
9485 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009486 }
9487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009488 return info;
9489 }
9490
9491 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9492 int flags) {
9493 synchronized (this) {
9494 ArrayList<ActivityManager.RunningServiceInfo> res
9495 = new ArrayList<ActivityManager.RunningServiceInfo>();
9496
9497 if (mServices.size() > 0) {
9498 Iterator<ServiceRecord> it = mServices.values().iterator();
9499 while (it.hasNext() && res.size() < maxNum) {
9500 res.add(makeRunningServiceInfoLocked(it.next()));
9501 }
9502 }
9503
9504 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9505 ServiceRecord r = mRestartingServices.get(i);
9506 ActivityManager.RunningServiceInfo info =
9507 makeRunningServiceInfoLocked(r);
9508 info.restarting = r.nextRestartTime;
9509 res.add(info);
9510 }
9511
9512 return res;
9513 }
9514 }
9515
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009516 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9517 synchronized (this) {
9518 ServiceRecord r = mServices.get(name);
9519 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009520 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9521 for (int i=0; i<conn.size(); i++) {
9522 if (conn.get(i).clientIntent != null) {
9523 return conn.get(i).clientIntent;
9524 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009525 }
9526 }
9527 }
9528 }
9529 return null;
9530 }
9531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009532 private final ServiceRecord findServiceLocked(ComponentName name,
9533 IBinder token) {
9534 ServiceRecord r = mServices.get(name);
9535 return r == token ? r : null;
9536 }
9537
9538 private final class ServiceLookupResult {
9539 final ServiceRecord record;
9540 final String permission;
9541
9542 ServiceLookupResult(ServiceRecord _record, String _permission) {
9543 record = _record;
9544 permission = _permission;
9545 }
9546 };
9547
9548 private ServiceLookupResult findServiceLocked(Intent service,
9549 String resolvedType) {
9550 ServiceRecord r = null;
9551 if (service.getComponent() != null) {
9552 r = mServices.get(service.getComponent());
9553 }
9554 if (r == null) {
9555 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9556 r = mServicesByIntent.get(filter);
9557 }
9558
9559 if (r == null) {
9560 try {
9561 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009562 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 service, resolvedType, 0);
9564 ServiceInfo sInfo =
9565 rInfo != null ? rInfo.serviceInfo : null;
9566 if (sInfo == null) {
9567 return null;
9568 }
9569
9570 ComponentName name = new ComponentName(
9571 sInfo.applicationInfo.packageName, sInfo.name);
9572 r = mServices.get(name);
9573 } catch (RemoteException ex) {
9574 // pm is in same process, this will never happen.
9575 }
9576 }
9577 if (r != null) {
9578 int callingPid = Binder.getCallingPid();
9579 int callingUid = Binder.getCallingUid();
9580 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009581 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009582 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009583 if (!r.exported) {
9584 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9585 + " from pid=" + callingPid
9586 + ", uid=" + callingUid
9587 + " that is not exported from uid " + r.appInfo.uid);
9588 return new ServiceLookupResult(null, "not exported from uid "
9589 + r.appInfo.uid);
9590 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009591 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009592 + " from pid=" + callingPid
9593 + ", uid=" + callingUid
9594 + " requires " + r.permission);
9595 return new ServiceLookupResult(null, r.permission);
9596 }
9597 return new ServiceLookupResult(r, null);
9598 }
9599 return null;
9600 }
9601
9602 private class ServiceRestarter implements Runnable {
9603 private ServiceRecord mService;
9604
9605 void setService(ServiceRecord service) {
9606 mService = service;
9607 }
9608
9609 public void run() {
9610 synchronized(ActivityManagerService.this) {
9611 performServiceRestartLocked(mService);
9612 }
9613 }
9614 }
9615
9616 private ServiceLookupResult retrieveServiceLocked(Intent service,
9617 String resolvedType, int callingPid, int callingUid) {
9618 ServiceRecord r = null;
9619 if (service.getComponent() != null) {
9620 r = mServices.get(service.getComponent());
9621 }
9622 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9623 r = mServicesByIntent.get(filter);
9624 if (r == null) {
9625 try {
9626 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009627 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009628 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009629 ServiceInfo sInfo =
9630 rInfo != null ? rInfo.serviceInfo : null;
9631 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009632 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009633 ": not found");
9634 return null;
9635 }
9636
9637 ComponentName name = new ComponentName(
9638 sInfo.applicationInfo.packageName, sInfo.name);
9639 r = mServices.get(name);
9640 if (r == null) {
9641 filter = new Intent.FilterComparison(service.cloneFilter());
9642 ServiceRestarter res = new ServiceRestarter();
9643 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9644 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9645 synchronized (stats) {
9646 ss = stats.getServiceStatsLocked(
9647 sInfo.applicationInfo.uid, sInfo.packageName,
9648 sInfo.name);
9649 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009650 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009651 res.setService(r);
9652 mServices.put(name, r);
9653 mServicesByIntent.put(filter, r);
9654
9655 // Make sure this component isn't in the pending list.
9656 int N = mPendingServices.size();
9657 for (int i=0; i<N; i++) {
9658 ServiceRecord pr = mPendingServices.get(i);
9659 if (pr.name.equals(name)) {
9660 mPendingServices.remove(i);
9661 i--;
9662 N--;
9663 }
9664 }
9665 }
9666 } catch (RemoteException ex) {
9667 // pm is in same process, this will never happen.
9668 }
9669 }
9670 if (r != null) {
9671 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009672 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009673 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009674 if (!r.exported) {
9675 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9676 + " from pid=" + callingPid
9677 + ", uid=" + callingUid
9678 + " that is not exported from uid " + r.appInfo.uid);
9679 return new ServiceLookupResult(null, "not exported from uid "
9680 + r.appInfo.uid);
9681 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009682 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009683 + " from pid=" + callingPid
9684 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685 + " requires " + r.permission);
9686 return new ServiceLookupResult(null, r.permission);
9687 }
9688 return new ServiceLookupResult(r, null);
9689 }
9690 return null;
9691 }
9692
Dianne Hackborn287952c2010-09-22 22:34:31 -07009693 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9694 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9695 + why + " of " + r + " in app " + r.app);
9696 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9697 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009698 long now = SystemClock.uptimeMillis();
9699 if (r.executeNesting == 0 && r.app != null) {
9700 if (r.app.executingServices.size() == 0) {
9701 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9702 msg.obj = r.app;
9703 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9704 }
9705 r.app.executingServices.add(r);
9706 }
9707 r.executeNesting++;
9708 r.executingStart = now;
9709 }
9710
9711 private final void sendServiceArgsLocked(ServiceRecord r,
9712 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009713 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009714 if (N == 0) {
9715 return;
9716 }
9717
Dianne Hackborn39792d22010-08-19 18:01:52 -07009718 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009719 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009720 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009721 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9722 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009723 if (si.intent == null && N > 1) {
9724 // If somehow we got a dummy null intent in the middle,
9725 // then skip it. DO NOT skip a null intent when it is
9726 // the only one in the list -- this is to support the
9727 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009728 continue;
9729 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009730 si.deliveredTime = SystemClock.uptimeMillis();
9731 r.deliveredStarts.add(si);
9732 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009733 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009734 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009735 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009736 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009737 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009738 if (!oomAdjusted) {
9739 oomAdjusted = true;
9740 updateOomAdjLocked(r.app);
9741 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009742 int flags = 0;
9743 if (si.deliveryCount > 0) {
9744 flags |= Service.START_FLAG_RETRY;
9745 }
9746 if (si.doneExecutingCount > 0) {
9747 flags |= Service.START_FLAG_REDELIVERY;
9748 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009749 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009750 } catch (RemoteException e) {
9751 // Remote process gone... we'll let the normal cleanup take
9752 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009753 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009754 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009755 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009756 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009757 break;
9758 }
9759 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009760 }
9761
9762 private final boolean requestServiceBindingLocked(ServiceRecord r,
9763 IntentBindRecord i, boolean rebind) {
9764 if (r.app == null || r.app.thread == null) {
9765 // If service is not currently running, can't yet bind.
9766 return false;
9767 }
9768 if ((!i.requested || rebind) && i.apps.size() > 0) {
9769 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009770 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009771 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9772 if (!rebind) {
9773 i.requested = true;
9774 }
9775 i.hasBound = true;
9776 i.doRebind = false;
9777 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009778 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009779 return false;
9780 }
9781 }
9782 return true;
9783 }
9784
9785 private final void requestServiceBindingsLocked(ServiceRecord r) {
9786 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9787 while (bindings.hasNext()) {
9788 IntentBindRecord i = bindings.next();
9789 if (!requestServiceBindingLocked(r, i, false)) {
9790 break;
9791 }
9792 }
9793 }
9794
9795 private final void realStartServiceLocked(ServiceRecord r,
9796 ProcessRecord app) throws RemoteException {
9797 if (app.thread == null) {
9798 throw new RemoteException();
9799 }
9800
9801 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009802 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009803
9804 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009805 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009806 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009807
9808 boolean created = false;
9809 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009810 mStringBuilder.setLength(0);
9811 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009812 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009813 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009814 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009815 synchronized (r.stats.getBatteryStats()) {
9816 r.stats.startLaunchedLocked();
9817 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009818 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009819 app.thread.scheduleCreateService(r, r.serviceInfo,
9820 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009821 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009822 created = true;
9823 } finally {
9824 if (!created) {
9825 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009826 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009827 }
9828 }
9829
9830 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009831
9832 // If the service is in the started state, and there are no
9833 // pending arguments, then fake up one so its onStartCommand() will
9834 // be called.
9835 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009836 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9837 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009838 }
9839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009840 sendServiceArgsLocked(r, true);
9841 }
9842
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009843 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9844 boolean allowCancel) {
9845 boolean canceled = false;
9846
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009847 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009848 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009849 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009850
Dianne Hackborn070783f2010-12-29 16:46:28 -08009851 if ((r.serviceInfo.applicationInfo.flags
9852 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9853 minDuration /= 4;
9854 }
9855
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009856 // Any delivered but not yet finished starts should be put back
9857 // on the pending list.
9858 final int N = r.deliveredStarts.size();
9859 if (N > 0) {
9860 for (int i=N-1; i>=0; i--) {
9861 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009862 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009863 if (si.intent == null) {
9864 // We'll generate this again if needed.
9865 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9866 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9867 r.pendingStarts.add(0, si);
9868 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9869 dur *= 2;
9870 if (minDuration < dur) minDuration = dur;
9871 if (resetTime < dur) resetTime = dur;
9872 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009873 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009874 + r.name);
9875 canceled = true;
9876 }
9877 }
9878 r.deliveredStarts.clear();
9879 }
9880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009881 r.totalRestartCount++;
9882 if (r.restartDelay == 0) {
9883 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009884 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009885 } else {
9886 // If it has been a "reasonably long time" since the service
9887 // was started, then reset our restart duration back to
9888 // the beginning, so we don't infinitely increase the duration
9889 // on a service that just occasionally gets killed (which is
9890 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009891 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009892 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009893 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009894 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009895 if ((r.serviceInfo.applicationInfo.flags
9896 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9897 // Services in peristent processes will restart much more
9898 // quickly, since they are pretty important. (Think SystemUI).
9899 r.restartDelay += minDuration/2;
9900 } else {
9901 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9902 if (r.restartDelay < minDuration) {
9903 r.restartDelay = minDuration;
9904 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009906 }
9907 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009908
9909 r.nextRestartTime = now + r.restartDelay;
9910
9911 // Make sure that we don't end up restarting a bunch of services
9912 // all at the same time.
9913 boolean repeat;
9914 do {
9915 repeat = false;
9916 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9917 ServiceRecord r2 = mRestartingServices.get(i);
9918 if (r2 != r && r.nextRestartTime
9919 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9920 && r.nextRestartTime
9921 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9922 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9923 r.restartDelay = r.nextRestartTime - now;
9924 repeat = true;
9925 break;
9926 }
9927 }
9928 } while (repeat);
9929
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009930 if (!mRestartingServices.contains(r)) {
9931 mRestartingServices.add(r);
9932 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009933
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009934 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009936 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009937 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009938 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009939 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009940 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009941 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009942 r.shortName, r.restartDelay);
9943
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009944 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009945 }
9946
9947 final void performServiceRestartLocked(ServiceRecord r) {
9948 if (!mRestartingServices.contains(r)) {
9949 return;
9950 }
9951 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9952 }
9953
9954 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9955 if (r.restartDelay == 0) {
9956 return false;
9957 }
9958 r.resetRestartCounter();
9959 mRestartingServices.remove(r);
9960 mHandler.removeCallbacks(r.restarter);
9961 return true;
9962 }
9963
9964 private final boolean bringUpServiceLocked(ServiceRecord r,
9965 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009966 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009967 //r.dump(" ");
9968
Dianne Hackborn36124872009-10-08 16:22:03 -07009969 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009970 sendServiceArgsLocked(r, false);
9971 return true;
9972 }
9973
9974 if (!whileRestarting && r.restartDelay > 0) {
9975 // If waiting for a restart, then do nothing.
9976 return true;
9977 }
9978
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009979 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009980
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009981 // We are now bringing the service up, so no longer in the
9982 // restarting state.
9983 mRestartingServices.remove(r);
9984
Dianne Hackborne7f97212011-02-24 14:40:20 -08009985 // Service is now being launched, its package can't be stopped.
9986 try {
9987 AppGlobals.getPackageManager().setPackageStoppedState(
9988 r.packageName, false);
9989 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009990 } catch (IllegalArgumentException e) {
9991 Slog.w(TAG, "Failed trying to unstop package "
9992 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009993 }
9994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009995 final String appName = r.processName;
9996 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9997 if (app != null && app.thread != null) {
9998 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07009999 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010000 realStartServiceLocked(r, app);
10001 return true;
10002 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010003 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010004 }
10005
10006 // If a dead object exception was thrown -- fall through to
10007 // restart the application.
10008 }
10009
Dianne Hackborn36124872009-10-08 16:22:03 -070010010 // Not running -- get it started, and enqueue this service record
10011 // to be executed when the app comes up.
10012 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10013 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010014 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010015 + r.appInfo.packageName + "/"
10016 + r.appInfo.uid + " for service "
10017 + r.intent.getIntent() + ": process is bad");
10018 bringDownServiceLocked(r, true);
10019 return false;
10020 }
10021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010022 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010023 mPendingServices.add(r);
10024 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010026 return true;
10027 }
10028
10029 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010030 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010031 //r.dump(" ");
10032
10033 // Does it still need to run?
10034 if (!force && r.startRequested) {
10035 return;
10036 }
10037 if (r.connections.size() > 0) {
10038 if (!force) {
10039 // XXX should probably keep a count of the number of auto-create
10040 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010041 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010042 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010043 ArrayList<ConnectionRecord> cr = it.next();
10044 for (int i=0; i<cr.size(); i++) {
10045 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10046 return;
10047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010048 }
10049 }
10050 }
10051
10052 // Report to all of the connections that the service is no longer
10053 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010054 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010055 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010056 ArrayList<ConnectionRecord> c = it.next();
10057 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010058 ConnectionRecord cr = c.get(i);
10059 // There is still a connection to the service that is
10060 // being brought down. Mark it as dead.
10061 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010062 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010063 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010064 } catch (Exception e) {
10065 Slog.w(TAG, "Failure disconnecting service " + r.name +
10066 " to connection " + c.get(i).conn.asBinder() +
10067 " (in " + c.get(i).binding.client.processName + ")", e);
10068 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010069 }
10070 }
10071 }
10072
10073 // Tell the service that it has been unbound.
10074 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10075 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10076 while (it.hasNext()) {
10077 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010078 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010079 + ": hasBound=" + ibr.hasBound);
10080 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10081 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010082 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010083 updateOomAdjLocked(r.app);
10084 ibr.hasBound = false;
10085 r.app.thread.scheduleUnbindService(r,
10086 ibr.intent.getIntent());
10087 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010088 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010089 + r.shortName, e);
10090 serviceDoneExecutingLocked(r, true);
10091 }
10092 }
10093 }
10094 }
10095
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010096 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010097 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010098 System.identityHashCode(r), r.shortName,
10099 (r.app != null) ? r.app.pid : -1);
10100
10101 mServices.remove(r.name);
10102 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010103 r.totalRestartCount = 0;
10104 unscheduleServiceRestartLocked(r);
10105
10106 // Also make sure it is not on the pending list.
10107 int N = mPendingServices.size();
10108 for (int i=0; i<N; i++) {
10109 if (mPendingServices.get(i) == r) {
10110 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010111 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010112 i--;
10113 N--;
10114 }
10115 }
10116
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010117 r.cancelNotification();
10118 r.isForeground = false;
10119 r.foregroundId = 0;
10120 r.foregroundNoti = null;
10121
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010122 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010123 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010124 r.pendingStarts.clear();
10125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010126 if (r.app != null) {
10127 synchronized (r.stats.getBatteryStats()) {
10128 r.stats.stopLaunchedLocked();
10129 }
10130 r.app.services.remove(r);
10131 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010132 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010133 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010134 mStoppingServices.add(r);
10135 updateOomAdjLocked(r.app);
10136 r.app.thread.scheduleStopService(r);
10137 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010138 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010139 + r.shortName, e);
10140 serviceDoneExecutingLocked(r, true);
10141 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010142 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010143 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010144 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010145 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010146 }
10147 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010148 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010149 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010150 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010151
10152 if (r.bindings.size() > 0) {
10153 r.bindings.clear();
10154 }
10155
10156 if (r.restarter instanceof ServiceRestarter) {
10157 ((ServiceRestarter)r.restarter).setService(null);
10158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010159 }
10160
10161 ComponentName startServiceLocked(IApplicationThread caller,
10162 Intent service, String resolvedType,
10163 int callingPid, int callingUid) {
10164 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010165 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010166 + " type=" + resolvedType + " args=" + service.getExtras());
10167
10168 if (caller != null) {
10169 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10170 if (callerApp == null) {
10171 throw new SecurityException(
10172 "Unable to find app for caller " + caller
10173 + " (pid=" + Binder.getCallingPid()
10174 + ") when starting service " + service);
10175 }
10176 }
10177
10178 ServiceLookupResult res =
10179 retrieveServiceLocked(service, resolvedType,
10180 callingPid, callingUid);
10181 if (res == null) {
10182 return null;
10183 }
10184 if (res.record == null) {
10185 return new ComponentName("!", res.permission != null
10186 ? res.permission : "private to package");
10187 }
10188 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010189 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10190 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010191 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010192 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010193 }
10194 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010195 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010196 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010197 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010198 r.lastActivity = SystemClock.uptimeMillis();
10199 synchronized (r.stats.getBatteryStats()) {
10200 r.stats.startRunningLocked();
10201 }
10202 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10203 return new ComponentName("!", "Service process is bad");
10204 }
10205 return r.name;
10206 }
10207 }
10208
10209 public ComponentName startService(IApplicationThread caller, Intent service,
10210 String resolvedType) {
10211 // Refuse possible leaked file descriptors
10212 if (service != null && service.hasFileDescriptors() == true) {
10213 throw new IllegalArgumentException("File descriptors passed in Intent");
10214 }
10215
10216 synchronized(this) {
10217 final int callingPid = Binder.getCallingPid();
10218 final int callingUid = Binder.getCallingUid();
10219 final long origId = Binder.clearCallingIdentity();
10220 ComponentName res = startServiceLocked(caller, service,
10221 resolvedType, callingPid, callingUid);
10222 Binder.restoreCallingIdentity(origId);
10223 return res;
10224 }
10225 }
10226
10227 ComponentName startServiceInPackage(int uid,
10228 Intent service, String resolvedType) {
10229 synchronized(this) {
10230 final long origId = Binder.clearCallingIdentity();
10231 ComponentName res = startServiceLocked(null, service,
10232 resolvedType, -1, uid);
10233 Binder.restoreCallingIdentity(origId);
10234 return res;
10235 }
10236 }
10237
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010238 private void stopServiceLocked(ServiceRecord service) {
10239 synchronized (service.stats.getBatteryStats()) {
10240 service.stats.stopRunningLocked();
10241 }
10242 service.startRequested = false;
10243 service.callStart = false;
10244 bringDownServiceLocked(service, false);
10245 }
10246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010247 public int stopService(IApplicationThread caller, Intent service,
10248 String resolvedType) {
10249 // Refuse possible leaked file descriptors
10250 if (service != null && service.hasFileDescriptors() == true) {
10251 throw new IllegalArgumentException("File descriptors passed in Intent");
10252 }
10253
10254 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010255 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010256 + " type=" + resolvedType);
10257
10258 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10259 if (caller != null && callerApp == null) {
10260 throw new SecurityException(
10261 "Unable to find app for caller " + caller
10262 + " (pid=" + Binder.getCallingPid()
10263 + ") when stopping service " + service);
10264 }
10265
10266 // If this service is active, make sure it is stopped.
10267 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10268 if (r != null) {
10269 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010270 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010271 try {
10272 stopServiceLocked(r.record);
10273 } finally {
10274 Binder.restoreCallingIdentity(origId);
10275 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010276 return 1;
10277 }
10278 return -1;
10279 }
10280 }
10281
10282 return 0;
10283 }
10284
10285 public IBinder peekService(Intent service, String resolvedType) {
10286 // Refuse possible leaked file descriptors
10287 if (service != null && service.hasFileDescriptors() == true) {
10288 throw new IllegalArgumentException("File descriptors passed in Intent");
10289 }
10290
10291 IBinder ret = null;
10292
10293 synchronized(this) {
10294 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10295
10296 if (r != null) {
10297 // r.record is null if findServiceLocked() failed the caller permission check
10298 if (r.record == null) {
10299 throw new SecurityException(
10300 "Permission Denial: Accessing service " + r.record.name
10301 + " from pid=" + Binder.getCallingPid()
10302 + ", uid=" + Binder.getCallingUid()
10303 + " requires " + r.permission);
10304 }
10305 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10306 if (ib != null) {
10307 ret = ib.binder;
10308 }
10309 }
10310 }
10311
10312 return ret;
10313 }
10314
10315 public boolean stopServiceToken(ComponentName className, IBinder token,
10316 int startId) {
10317 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010318 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010319 + " " + token + " startId=" + startId);
10320 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010321 if (r != null) {
10322 if (startId >= 0) {
10323 // Asked to only stop if done with all work. Note that
10324 // to avoid leaks, we will take this as dropping all
10325 // start items up to and including this one.
10326 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10327 if (si != null) {
10328 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010329 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10330 cur.removeUriPermissionsLocked();
10331 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010332 break;
10333 }
10334 }
10335 }
10336
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010337 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010338 return false;
10339 }
10340
10341 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010342 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010343 + " is last, but have " + r.deliveredStarts.size()
10344 + " remaining args");
10345 }
10346 }
10347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010348 synchronized (r.stats.getBatteryStats()) {
10349 r.stats.stopRunningLocked();
10350 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010351 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010352 }
10353 final long origId = Binder.clearCallingIdentity();
10354 bringDownServiceLocked(r, false);
10355 Binder.restoreCallingIdentity(origId);
10356 return true;
10357 }
10358 }
10359 return false;
10360 }
10361
10362 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010363 int id, Notification notification, boolean removeNotification) {
10364 final long origId = Binder.clearCallingIdentity();
10365 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010366 synchronized(this) {
10367 ServiceRecord r = findServiceLocked(className, token);
10368 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010369 if (id != 0) {
10370 if (notification == null) {
10371 throw new IllegalArgumentException("null notification");
10372 }
10373 if (r.foregroundId != id) {
10374 r.cancelNotification();
10375 r.foregroundId = id;
10376 }
10377 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10378 r.foregroundNoti = notification;
10379 r.isForeground = true;
10380 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010381 if (r.app != null) {
10382 updateServiceForegroundLocked(r.app, true);
10383 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010384 } else {
10385 if (r.isForeground) {
10386 r.isForeground = false;
10387 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010388 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010389 updateServiceForegroundLocked(r.app, true);
10390 }
10391 }
10392 if (removeNotification) {
10393 r.cancelNotification();
10394 r.foregroundId = 0;
10395 r.foregroundNoti = null;
10396 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010397 }
10398 }
10399 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010400 } finally {
10401 Binder.restoreCallingIdentity(origId);
10402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010403 }
10404
10405 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10406 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010407 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010408 if (sr.isForeground) {
10409 anyForeground = true;
10410 break;
10411 }
10412 }
10413 if (anyForeground != proc.foregroundServices) {
10414 proc.foregroundServices = anyForeground;
10415 if (oomAdj) {
10416 updateOomAdjLocked();
10417 }
10418 }
10419 }
10420
10421 public int bindService(IApplicationThread caller, IBinder token,
10422 Intent service, String resolvedType,
10423 IServiceConnection connection, int flags) {
10424 // Refuse possible leaked file descriptors
10425 if (service != null && service.hasFileDescriptors() == true) {
10426 throw new IllegalArgumentException("File descriptors passed in Intent");
10427 }
10428
10429 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010430 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010431 + " type=" + resolvedType + " conn=" + connection.asBinder()
10432 + " flags=0x" + Integer.toHexString(flags));
10433 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10434 if (callerApp == null) {
10435 throw new SecurityException(
10436 "Unable to find app for caller " + caller
10437 + " (pid=" + Binder.getCallingPid()
10438 + ") when binding service " + service);
10439 }
10440
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010441 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010442 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010443 activity = mMainStack.isInStackLocked(token);
10444 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010445 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010446 return 0;
10447 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010448 }
10449
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010450 int clientLabel = 0;
10451 PendingIntent clientIntent = null;
10452
10453 if (callerApp.info.uid == Process.SYSTEM_UID) {
10454 // Hacky kind of thing -- allow system stuff to tell us
10455 // what they are, so we can report this elsewhere for
10456 // others to know why certain services are running.
10457 try {
10458 clientIntent = (PendingIntent)service.getParcelableExtra(
10459 Intent.EXTRA_CLIENT_INTENT);
10460 } catch (RuntimeException e) {
10461 }
10462 if (clientIntent != null) {
10463 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10464 if (clientLabel != 0) {
10465 // There are no useful extras in the intent, trash them.
10466 // System code calling with this stuff just needs to know
10467 // this will happen.
10468 service = service.cloneFilter();
10469 }
10470 }
10471 }
10472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010473 ServiceLookupResult res =
10474 retrieveServiceLocked(service, resolvedType,
10475 Binder.getCallingPid(), Binder.getCallingUid());
10476 if (res == null) {
10477 return 0;
10478 }
10479 if (res.record == null) {
10480 return -1;
10481 }
10482 ServiceRecord s = res.record;
10483
10484 final long origId = Binder.clearCallingIdentity();
10485
10486 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010487 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010488 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010489 }
10490
10491 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10492 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010493 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010494
10495 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010496 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10497 if (clist == null) {
10498 clist = new ArrayList<ConnectionRecord>();
10499 s.connections.put(binder, clist);
10500 }
10501 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010502 b.connections.add(c);
10503 if (activity != null) {
10504 if (activity.connections == null) {
10505 activity.connections = new HashSet<ConnectionRecord>();
10506 }
10507 activity.connections.add(c);
10508 }
10509 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010510 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10511 b.client.hasAboveClient = true;
10512 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010513 clist = mServiceConnections.get(binder);
10514 if (clist == null) {
10515 clist = new ArrayList<ConnectionRecord>();
10516 mServiceConnections.put(binder, clist);
10517 }
10518 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010519
10520 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10521 s.lastActivity = SystemClock.uptimeMillis();
10522 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10523 return 0;
10524 }
10525 }
10526
10527 if (s.app != null) {
10528 // This could have made the service more important.
10529 updateOomAdjLocked(s.app);
10530 }
10531
Joe Onorato8a9b2202010-02-26 18:56:32 -080010532 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010533 + ": received=" + b.intent.received
10534 + " apps=" + b.intent.apps.size()
10535 + " doRebind=" + b.intent.doRebind);
10536
10537 if (s.app != null && b.intent.received) {
10538 // Service is already running, so we can immediately
10539 // publish the connection.
10540 try {
10541 c.conn.connected(s.name, b.intent.binder);
10542 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010543 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010544 + " to connection " + c.conn.asBinder()
10545 + " (in " + c.binding.client.processName + ")", e);
10546 }
10547
10548 // If this is the first app connected back to this binding,
10549 // and the service had previously asked to be told when
10550 // rebound, then do so.
10551 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10552 requestServiceBindingLocked(s, b.intent, true);
10553 }
10554 } else if (!b.intent.requested) {
10555 requestServiceBindingLocked(s, b.intent, false);
10556 }
10557
10558 Binder.restoreCallingIdentity(origId);
10559 }
10560
10561 return 1;
10562 }
10563
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010564 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010565 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010566 IBinder binder = c.conn.asBinder();
10567 AppBindRecord b = c.binding;
10568 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010569 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10570 if (clist != null) {
10571 clist.remove(c);
10572 if (clist.size() == 0) {
10573 s.connections.remove(binder);
10574 }
10575 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010576 b.connections.remove(c);
10577 if (c.activity != null && c.activity != skipAct) {
10578 if (c.activity.connections != null) {
10579 c.activity.connections.remove(c);
10580 }
10581 }
10582 if (b.client != skipApp) {
10583 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010584 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10585 b.client.updateHasAboveClientLocked();
10586 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010587 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010588 clist = mServiceConnections.get(binder);
10589 if (clist != null) {
10590 clist.remove(c);
10591 if (clist.size() == 0) {
10592 mServiceConnections.remove(binder);
10593 }
10594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010595
10596 if (b.connections.size() == 0) {
10597 b.intent.apps.remove(b.client);
10598 }
10599
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010600 if (!c.serviceDead) {
10601 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10602 + ": shouldUnbind=" + b.intent.hasBound);
10603 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10604 && b.intent.hasBound) {
10605 try {
10606 bumpServiceExecutingLocked(s, "unbind");
10607 updateOomAdjLocked(s.app);
10608 b.intent.hasBound = false;
10609 // Assume the client doesn't want to know about a rebind;
10610 // we will deal with that later if it asks for one.
10611 b.intent.doRebind = false;
10612 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10613 } catch (Exception e) {
10614 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10615 serviceDoneExecutingLocked(s, true);
10616 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010617 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010618
10619 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10620 bringDownServiceLocked(s, false);
10621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010622 }
10623 }
10624
10625 public boolean unbindService(IServiceConnection connection) {
10626 synchronized (this) {
10627 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010628 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010629 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10630 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010631 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010632 + connection.asBinder());
10633 return false;
10634 }
10635
10636 final long origId = Binder.clearCallingIdentity();
10637
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010638 while (clist.size() > 0) {
10639 ConnectionRecord r = clist.get(0);
10640 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010641
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010642 if (r.binding.service.app != null) {
10643 // This could have made the service less important.
10644 updateOomAdjLocked(r.binding.service.app);
10645 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010646 }
10647
10648 Binder.restoreCallingIdentity(origId);
10649 }
10650
10651 return true;
10652 }
10653
10654 public void publishService(IBinder token, Intent intent, IBinder service) {
10655 // Refuse possible leaked file descriptors
10656 if (intent != null && intent.hasFileDescriptors() == true) {
10657 throw new IllegalArgumentException("File descriptors passed in Intent");
10658 }
10659
10660 synchronized(this) {
10661 if (!(token instanceof ServiceRecord)) {
10662 throw new IllegalArgumentException("Invalid service token");
10663 }
10664 ServiceRecord r = (ServiceRecord)token;
10665
10666 final long origId = Binder.clearCallingIdentity();
10667
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010668 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010669 + " " + intent + ": " + service);
10670 if (r != null) {
10671 Intent.FilterComparison filter
10672 = new Intent.FilterComparison(intent);
10673 IntentBindRecord b = r.bindings.get(filter);
10674 if (b != null && !b.received) {
10675 b.binder = service;
10676 b.requested = true;
10677 b.received = true;
10678 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010679 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010680 = r.connections.values().iterator();
10681 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010682 ArrayList<ConnectionRecord> clist = it.next();
10683 for (int i=0; i<clist.size(); i++) {
10684 ConnectionRecord c = clist.get(i);
10685 if (!filter.equals(c.binding.intent.intent)) {
10686 if (DEBUG_SERVICE) Slog.v(
10687 TAG, "Not publishing to: " + c);
10688 if (DEBUG_SERVICE) Slog.v(
10689 TAG, "Bound intent: " + c.binding.intent.intent);
10690 if (DEBUG_SERVICE) Slog.v(
10691 TAG, "Published intent: " + intent);
10692 continue;
10693 }
10694 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10695 try {
10696 c.conn.connected(r.name, service);
10697 } catch (Exception e) {
10698 Slog.w(TAG, "Failure sending service " + r.name +
10699 " to connection " + c.conn.asBinder() +
10700 " (in " + c.binding.client.processName + ")", e);
10701 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010702 }
10703 }
10704 }
10705 }
10706
10707 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10708
10709 Binder.restoreCallingIdentity(origId);
10710 }
10711 }
10712 }
10713
10714 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10715 // Refuse possible leaked file descriptors
10716 if (intent != null && intent.hasFileDescriptors() == true) {
10717 throw new IllegalArgumentException("File descriptors passed in Intent");
10718 }
10719
10720 synchronized(this) {
10721 if (!(token instanceof ServiceRecord)) {
10722 throw new IllegalArgumentException("Invalid service token");
10723 }
10724 ServiceRecord r = (ServiceRecord)token;
10725
10726 final long origId = Binder.clearCallingIdentity();
10727
10728 if (r != null) {
10729 Intent.FilterComparison filter
10730 = new Intent.FilterComparison(intent);
10731 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010732 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010733 + " at " + b + ": apps="
10734 + (b != null ? b.apps.size() : 0));
10735 if (b != null) {
10736 if (b.apps.size() > 0) {
10737 // Applications have already bound since the last
10738 // unbind, so just rebind right here.
10739 requestServiceBindingLocked(r, b, true);
10740 } else {
10741 // Note to tell the service the next time there is
10742 // a new client.
10743 b.doRebind = true;
10744 }
10745 }
10746
10747 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10748
10749 Binder.restoreCallingIdentity(origId);
10750 }
10751 }
10752 }
10753
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010754 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010755 synchronized(this) {
10756 if (!(token instanceof ServiceRecord)) {
10757 throw new IllegalArgumentException("Invalid service token");
10758 }
10759 ServiceRecord r = (ServiceRecord)token;
10760 boolean inStopping = mStoppingServices.contains(token);
10761 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010762 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010763 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010764 + " with incorrect token: given " + token
10765 + ", expected " + r);
10766 return;
10767 }
10768
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010769 if (type == 1) {
10770 // This is a call from a service start... take care of
10771 // book-keeping.
10772 r.callStart = true;
10773 switch (res) {
10774 case Service.START_STICKY_COMPATIBILITY:
10775 case Service.START_STICKY: {
10776 // We are done with the associated start arguments.
10777 r.findDeliveredStart(startId, true);
10778 // Don't stop if killed.
10779 r.stopIfKilled = false;
10780 break;
10781 }
10782 case Service.START_NOT_STICKY: {
10783 // We are done with the associated start arguments.
10784 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010785 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010786 // There is no more work, and this service
10787 // doesn't want to hang around if killed.
10788 r.stopIfKilled = true;
10789 }
10790 break;
10791 }
10792 case Service.START_REDELIVER_INTENT: {
10793 // We'll keep this item until they explicitly
10794 // call stop for it, but keep track of the fact
10795 // that it was delivered.
10796 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10797 if (si != null) {
10798 si.deliveryCount = 0;
10799 si.doneExecutingCount++;
10800 // Don't stop if killed.
10801 r.stopIfKilled = true;
10802 }
10803 break;
10804 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010805 case Service.START_TASK_REMOVED_COMPLETE: {
10806 // Special processing for onTaskRemoved(). Don't
10807 // impact normal onStartCommand() processing.
10808 r.findDeliveredStart(startId, true);
10809 break;
10810 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010811 default:
10812 throw new IllegalArgumentException(
10813 "Unknown service start result: " + res);
10814 }
10815 if (res == Service.START_STICKY_COMPATIBILITY) {
10816 r.callStart = false;
10817 }
10818 }
10819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010820 final long origId = Binder.clearCallingIdentity();
10821 serviceDoneExecutingLocked(r, inStopping);
10822 Binder.restoreCallingIdentity(origId);
10823 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010824 Slog.w(TAG, "Done executing unknown service from pid "
10825 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010826 }
10827 }
10828 }
10829
10830 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010831 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10832 + ": nesting=" + r.executeNesting
10833 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010834 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010835 r.executeNesting--;
10836 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010837 if (DEBUG_SERVICE) Slog.v(TAG,
10838 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010839 r.app.executingServices.remove(r);
10840 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010841 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10842 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010843 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10844 }
10845 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010846 if (DEBUG_SERVICE) Slog.v(TAG,
10847 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010848 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010849 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010850 }
10851 updateOomAdjLocked(r.app);
10852 }
10853 }
10854
10855 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010856 String anrMessage = null;
10857
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010858 synchronized(this) {
10859 if (proc.executingServices.size() == 0 || proc.thread == null) {
10860 return;
10861 }
10862 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10863 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10864 ServiceRecord timeout = null;
10865 long nextTime = 0;
10866 while (it.hasNext()) {
10867 ServiceRecord sr = it.next();
10868 if (sr.executingStart < maxTime) {
10869 timeout = sr;
10870 break;
10871 }
10872 if (sr.executingStart > nextTime) {
10873 nextTime = sr.executingStart;
10874 }
10875 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010876 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010877 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010878 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010879 } else {
10880 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10881 msg.obj = proc;
10882 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10883 }
10884 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010885
10886 if (anrMessage != null) {
10887 appNotResponding(proc, null, null, anrMessage);
10888 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010889 }
10890
10891 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010892 // BACKUP AND RESTORE
10893 // =========================================================
10894
10895 // Cause the target app to be launched if necessary and its backup agent
10896 // instantiated. The backup agent will invoke backupAgentCreated() on the
10897 // activity manager to announce its creation.
10898 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010899 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010900 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10901
10902 synchronized(this) {
10903 // !!! TODO: currently no check here that we're already bound
10904 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10905 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10906 synchronized (stats) {
10907 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10908 }
10909
Dianne Hackborne7f97212011-02-24 14:40:20 -080010910 // Backup agent is now in use, its package can't be stopped.
10911 try {
10912 AppGlobals.getPackageManager().setPackageStoppedState(
10913 app.packageName, false);
10914 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010915 } catch (IllegalArgumentException e) {
10916 Slog.w(TAG, "Failed trying to unstop package "
10917 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010918 }
10919
Christopher Tate181fafa2009-05-14 11:12:14 -070010920 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070010921 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10922 ? new ComponentName(app.packageName, app.backupAgentName)
10923 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070010924 // startProcessLocked() returns existing proc's record if it's already running
10925 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010926 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010927 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010928 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010929 return false;
10930 }
10931
10932 r.app = proc;
10933 mBackupTarget = r;
10934 mBackupAppName = app.packageName;
10935
Christopher Tate6fa95972009-06-05 18:43:55 -070010936 // Try not to kill the process during backup
10937 updateOomAdjLocked(proc);
10938
Christopher Tate181fafa2009-05-14 11:12:14 -070010939 // If the process is already attached, schedule the creation of the backup agent now.
10940 // If it is not yet live, this will be done when it attaches to the framework.
10941 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010942 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010943 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010944 proc.thread.scheduleCreateBackupAgent(app,
10945 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010946 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010947 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010948 }
10949 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010950 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010951 }
10952 // Invariants: at this point, the target app process exists and the application
10953 // is either already running or in the process of coming up. mBackupTarget and
10954 // mBackupAppName describe the app, so that when it binds back to the AM we
10955 // know that it's scheduled for a backup-agent operation.
10956 }
10957
10958 return true;
10959 }
10960
10961 // A backup agent has just come up
10962 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010963 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010964 + " = " + agent);
10965
10966 synchronized(this) {
10967 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010968 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010969 return;
10970 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010971 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010972
Dianne Hackborn06740692010-09-22 22:46:21 -070010973 long oldIdent = Binder.clearCallingIdentity();
10974 try {
10975 IBackupManager bm = IBackupManager.Stub.asInterface(
10976 ServiceManager.getService(Context.BACKUP_SERVICE));
10977 bm.agentConnected(agentPackageName, agent);
10978 } catch (RemoteException e) {
10979 // can't happen; the backup manager service is local
10980 } catch (Exception e) {
10981 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10982 e.printStackTrace();
10983 } finally {
10984 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010985 }
10986 }
10987
10988 // done with this agent
10989 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010990 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010991 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010992 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010993 return;
10994 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010995
10996 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010997 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010998 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010999 return;
11000 }
11001
Christopher Tate181fafa2009-05-14 11:12:14 -070011002 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011003 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011004 return;
11005 }
11006
Christopher Tate6fa95972009-06-05 18:43:55 -070011007 ProcessRecord proc = mBackupTarget.app;
11008 mBackupTarget = null;
11009 mBackupAppName = null;
11010
11011 // Not backing this app up any more; reset its OOM adjustment
11012 updateOomAdjLocked(proc);
11013
Christopher Tatec7b31e32009-06-10 15:49:30 -070011014 // If the app crashed during backup, 'thread' will be null here
11015 if (proc.thread != null) {
11016 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011017 proc.thread.scheduleDestroyBackupAgent(appInfo,
11018 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011019 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011020 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011021 e.printStackTrace();
11022 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011023 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011024 }
11025 }
11026 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011027 // BROADCASTS
11028 // =========================================================
11029
Josh Bartel7f208742010-02-25 11:01:44 -060011030 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011031 List cur) {
11032 final ContentResolver resolver = mContext.getContentResolver();
11033 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11034 if (list == null) {
11035 return cur;
11036 }
11037 int N = list.size();
11038 for (int i=0; i<N; i++) {
11039 Intent intent = list.get(i);
11040 if (filter.match(resolver, intent, true, TAG) >= 0) {
11041 if (cur == null) {
11042 cur = new ArrayList<Intent>();
11043 }
11044 cur.add(intent);
11045 }
11046 }
11047 return cur;
11048 }
11049
11050 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011051 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011052 + mBroadcastsScheduled);
11053
11054 if (mBroadcastsScheduled) {
11055 return;
11056 }
11057 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11058 mBroadcastsScheduled = true;
11059 }
11060
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011061 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011062 IIntentReceiver receiver, IntentFilter filter, String permission) {
11063 synchronized(this) {
11064 ProcessRecord callerApp = null;
11065 if (caller != null) {
11066 callerApp = getRecordForAppLocked(caller);
11067 if (callerApp == null) {
11068 throw new SecurityException(
11069 "Unable to find app for caller " + caller
11070 + " (pid=" + Binder.getCallingPid()
11071 + ") when registering receiver " + receiver);
11072 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011073 if (callerApp.info.uid != Process.SYSTEM_UID &&
11074 !callerApp.pkgList.contains(callerPackage)) {
11075 throw new SecurityException("Given caller package " + callerPackage
11076 + " is not running in process " + callerApp);
11077 }
11078 } else {
11079 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011080 }
11081
11082 List allSticky = null;
11083
11084 // Look for any matching sticky broadcasts...
11085 Iterator actions = filter.actionsIterator();
11086 if (actions != null) {
11087 while (actions.hasNext()) {
11088 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011089 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011090 }
11091 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011092 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011093 }
11094
11095 // The first sticky in the list is returned directly back to
11096 // the client.
11097 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11098
Joe Onorato8a9b2202010-02-26 18:56:32 -080011099 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011100 + ": " + sticky);
11101
11102 if (receiver == null) {
11103 return sticky;
11104 }
11105
11106 ReceiverList rl
11107 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11108 if (rl == null) {
11109 rl = new ReceiverList(this, callerApp,
11110 Binder.getCallingPid(),
11111 Binder.getCallingUid(), receiver);
11112 if (rl.app != null) {
11113 rl.app.receivers.add(rl);
11114 } else {
11115 try {
11116 receiver.asBinder().linkToDeath(rl, 0);
11117 } catch (RemoteException e) {
11118 return sticky;
11119 }
11120 rl.linkedToDeath = true;
11121 }
11122 mRegisteredReceivers.put(receiver.asBinder(), rl);
11123 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011124 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011125 rl.add(bf);
11126 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011127 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011128 }
11129 mReceiverResolver.addFilter(bf);
11130
11131 // Enqueue broadcasts for all existing stickies that match
11132 // this filter.
11133 if (allSticky != null) {
11134 ArrayList receivers = new ArrayList();
11135 receivers.add(bf);
11136
11137 int N = allSticky.size();
11138 for (int i=0; i<N; i++) {
11139 Intent intent = (Intent)allSticky.get(i);
11140 BroadcastRecord r = new BroadcastRecord(intent, null,
11141 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011142 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011143 if (mParallelBroadcasts.size() == 0) {
11144 scheduleBroadcastsLocked();
11145 }
11146 mParallelBroadcasts.add(r);
11147 }
11148 }
11149
11150 return sticky;
11151 }
11152 }
11153
11154 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011155 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011156
11157 boolean doNext = false;
11158
11159 synchronized(this) {
11160 ReceiverList rl
11161 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11162 if (rl != null) {
11163 if (rl.curBroadcast != null) {
11164 BroadcastRecord r = rl.curBroadcast;
11165 doNext = finishReceiverLocked(
11166 receiver.asBinder(), r.resultCode, r.resultData,
11167 r.resultExtras, r.resultAbort, true);
11168 }
11169
11170 if (rl.app != null) {
11171 rl.app.receivers.remove(rl);
11172 }
11173 removeReceiverLocked(rl);
11174 if (rl.linkedToDeath) {
11175 rl.linkedToDeath = false;
11176 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11177 }
11178 }
11179 }
11180
11181 if (!doNext) {
11182 return;
11183 }
11184
11185 final long origId = Binder.clearCallingIdentity();
11186 processNextBroadcast(false);
11187 trimApplications();
11188 Binder.restoreCallingIdentity(origId);
11189 }
11190
11191 void removeReceiverLocked(ReceiverList rl) {
11192 mRegisteredReceivers.remove(rl.receiver.asBinder());
11193 int N = rl.size();
11194 for (int i=0; i<N; i++) {
11195 mReceiverResolver.removeFilter(rl.get(i));
11196 }
11197 }
11198
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011199 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11200 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11201 ProcessRecord r = mLruProcesses.get(i);
11202 if (r.thread != null) {
11203 try {
11204 r.thread.dispatchPackageBroadcast(cmd, packages);
11205 } catch (RemoteException ex) {
11206 }
11207 }
11208 }
11209 }
11210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011211 private final int broadcastIntentLocked(ProcessRecord callerApp,
11212 String callerPackage, Intent intent, String resolvedType,
11213 IIntentReceiver resultTo, int resultCode, String resultData,
11214 Bundle map, String requiredPermission,
11215 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11216 intent = new Intent(intent);
11217
Dianne Hackborne7f97212011-02-24 14:40:20 -080011218 // By default broadcasts do not go to stopped apps.
11219 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11220
Joe Onorato8a9b2202010-02-26 18:56:32 -080011221 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011222 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11223 + " ordered=" + ordered);
11224 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011225 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011226 }
11227
11228 // Handle special intents: if this broadcast is from the package
11229 // manager about a package being removed, we need to remove all of
11230 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011231 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011232 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011233 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11234 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011235 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011236 || uidRemoved) {
11237 if (checkComponentPermission(
11238 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011239 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011240 == PackageManager.PERMISSION_GRANTED) {
11241 if (uidRemoved) {
11242 final Bundle intentExtras = intent.getExtras();
11243 final int uid = intentExtras != null
11244 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11245 if (uid >= 0) {
11246 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11247 synchronized (bs) {
11248 bs.removeUidStatsLocked(uid);
11249 }
11250 }
11251 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011252 // If resources are unvailble just force stop all
11253 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011254 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011255 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11256 if (list != null && (list.length > 0)) {
11257 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011258 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011259 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011260 sendPackageBroadcastLocked(
11261 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011262 }
11263 } else {
11264 Uri data = intent.getData();
11265 String ssp;
11266 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11267 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11268 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011269 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011270 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011271 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011272 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11273 new String[] {ssp});
11274 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011275 }
11276 }
11277 }
11278 } else {
11279 String msg = "Permission Denial: " + intent.getAction()
11280 + " broadcast from " + callerPackage + " (pid=" + callingPid
11281 + ", uid=" + callingUid + ")"
11282 + " requires "
11283 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011284 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011285 throw new SecurityException(msg);
11286 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011287
11288 // Special case for adding a package: by default turn on compatibility
11289 // mode.
11290 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011291 Uri data = intent.getData();
11292 String ssp;
11293 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11294 mCompatModePackages.handlePackageAddedLocked(ssp,
11295 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011296 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011297 }
11298
11299 /*
11300 * If this is the time zone changed action, queue up a message that will reset the timezone
11301 * of all currently running processes. This message will get queued up before the broadcast
11302 * happens.
11303 */
11304 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11305 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11306 }
11307
Robert Greenwalt03595d02010-11-02 14:08:23 -070011308 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11309 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11310 }
11311
Robert Greenwalt434203a2010-10-11 16:00:27 -070011312 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11313 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11314 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11315 }
11316
Dianne Hackborn854060af2009-07-09 18:14:31 -070011317 /*
11318 * Prevent non-system code (defined here to be non-persistent
11319 * processes) from sending protected broadcasts.
11320 */
11321 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11322 || callingUid == Process.SHELL_UID || callingUid == 0) {
11323 // Always okay.
11324 } else if (callerApp == null || !callerApp.persistent) {
11325 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011326 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011327 intent.getAction())) {
11328 String msg = "Permission Denial: not allowed to send broadcast "
11329 + intent.getAction() + " from pid="
11330 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011331 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011332 throw new SecurityException(msg);
11333 }
11334 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011335 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011336 return BROADCAST_SUCCESS;
11337 }
11338 }
11339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011340 // Add to the sticky list if requested.
11341 if (sticky) {
11342 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11343 callingPid, callingUid)
11344 != PackageManager.PERMISSION_GRANTED) {
11345 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11346 + callingPid + ", uid=" + callingUid
11347 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011348 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011349 throw new SecurityException(msg);
11350 }
11351 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011352 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011353 + " and enforce permission " + requiredPermission);
11354 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11355 }
11356 if (intent.getComponent() != null) {
11357 throw new SecurityException(
11358 "Sticky broadcasts can't target a specific component");
11359 }
11360 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11361 if (list == null) {
11362 list = new ArrayList<Intent>();
11363 mStickyBroadcasts.put(intent.getAction(), list);
11364 }
11365 int N = list.size();
11366 int i;
11367 for (i=0; i<N; i++) {
11368 if (intent.filterEquals(list.get(i))) {
11369 // This sticky already exists, replace it.
11370 list.set(i, new Intent(intent));
11371 break;
11372 }
11373 }
11374 if (i >= N) {
11375 list.add(new Intent(intent));
11376 }
11377 }
11378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011379 // Figure out who all will receive this broadcast.
11380 List receivers = null;
11381 List<BroadcastFilter> registeredReceivers = null;
11382 try {
11383 if (intent.getComponent() != null) {
11384 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011385 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011386 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011387 if (ai != null) {
11388 receivers = new ArrayList();
11389 ResolveInfo ri = new ResolveInfo();
11390 ri.activityInfo = ai;
11391 receivers.add(ri);
11392 }
11393 } else {
11394 // Need to resolve the intent to interested receivers...
11395 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11396 == 0) {
11397 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011398 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011399 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011400 }
Mihai Preda074edef2009-05-18 17:13:31 +020011401 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011402 }
11403 } catch (RemoteException ex) {
11404 // pm is in same process, this will never happen.
11405 }
11406
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011407 final boolean replacePending =
11408 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11409
Joe Onorato8a9b2202010-02-26 18:56:32 -080011410 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011411 + " replacePending=" + replacePending);
11412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011413 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11414 if (!ordered && NR > 0) {
11415 // If we are not serializing this broadcast, then send the
11416 // registered receivers separately so they don't wait for the
11417 // components to be launched.
11418 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11419 callerPackage, callingPid, callingUid, requiredPermission,
11420 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011421 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011422 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011423 TAG, "Enqueueing parallel broadcast " + r
11424 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011425 boolean replaced = false;
11426 if (replacePending) {
11427 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11428 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011429 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011430 "***** DROPPING PARALLEL: " + intent);
11431 mParallelBroadcasts.set(i, r);
11432 replaced = true;
11433 break;
11434 }
11435 }
11436 }
11437 if (!replaced) {
11438 mParallelBroadcasts.add(r);
11439 scheduleBroadcastsLocked();
11440 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011441 registeredReceivers = null;
11442 NR = 0;
11443 }
11444
11445 // Merge into one list.
11446 int ir = 0;
11447 if (receivers != null) {
11448 // A special case for PACKAGE_ADDED: do not allow the package
11449 // being added to see this broadcast. This prevents them from
11450 // using this as a back door to get run as soon as they are
11451 // installed. Maybe in the future we want to have a special install
11452 // broadcast or such for apps, but we'd like to deliberately make
11453 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011454 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011455 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11456 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11457 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011458 Uri data = intent.getData();
11459 if (data != null) {
11460 String pkgName = data.getSchemeSpecificPart();
11461 if (pkgName != null) {
11462 skipPackages = new String[] { pkgName };
11463 }
11464 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011465 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011466 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011467 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011468 if (skipPackages != null && (skipPackages.length > 0)) {
11469 for (String skipPackage : skipPackages) {
11470 if (skipPackage != null) {
11471 int NT = receivers.size();
11472 for (int it=0; it<NT; it++) {
11473 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11474 if (curt.activityInfo.packageName.equals(skipPackage)) {
11475 receivers.remove(it);
11476 it--;
11477 NT--;
11478 }
11479 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011480 }
11481 }
11482 }
11483
11484 int NT = receivers != null ? receivers.size() : 0;
11485 int it = 0;
11486 ResolveInfo curt = null;
11487 BroadcastFilter curr = null;
11488 while (it < NT && ir < NR) {
11489 if (curt == null) {
11490 curt = (ResolveInfo)receivers.get(it);
11491 }
11492 if (curr == null) {
11493 curr = registeredReceivers.get(ir);
11494 }
11495 if (curr.getPriority() >= curt.priority) {
11496 // Insert this broadcast record into the final list.
11497 receivers.add(it, curr);
11498 ir++;
11499 curr = null;
11500 it++;
11501 NT++;
11502 } else {
11503 // Skip to the next ResolveInfo in the final list.
11504 it++;
11505 curt = null;
11506 }
11507 }
11508 }
11509 while (ir < NR) {
11510 if (receivers == null) {
11511 receivers = new ArrayList();
11512 }
11513 receivers.add(registeredReceivers.get(ir));
11514 ir++;
11515 }
11516
11517 if ((receivers != null && receivers.size() > 0)
11518 || resultTo != null) {
11519 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11520 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011521 receivers, resultTo, resultCode, resultData, map, ordered,
11522 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011523 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011524 TAG, "Enqueueing ordered broadcast " + r
11525 + ": prev had " + mOrderedBroadcasts.size());
11526 if (DEBUG_BROADCAST) {
11527 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011528 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011529 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011530 boolean replaced = false;
11531 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011532 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011533 if (intent.filterEquals(mOrderedBroadcasts.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 ORDERED: " + intent);
11536 mOrderedBroadcasts.set(i, r);
11537 replaced = true;
11538 break;
11539 }
11540 }
11541 }
11542 if (!replaced) {
11543 mOrderedBroadcasts.add(r);
11544 scheduleBroadcastsLocked();
11545 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011546 }
11547
11548 return BROADCAST_SUCCESS;
11549 }
11550
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011551 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011552 // Refuse possible leaked file descriptors
11553 if (intent != null && intent.hasFileDescriptors() == true) {
11554 throw new IllegalArgumentException("File descriptors passed in Intent");
11555 }
11556
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011557 int flags = intent.getFlags();
11558
11559 if (!mProcessesReady) {
11560 // if the caller really truly claims to know what they're doing, go
11561 // ahead and allow the broadcast without launching any receivers
11562 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11563 intent = new Intent(intent);
11564 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11565 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11566 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11567 + " before boot completion");
11568 throw new IllegalStateException("Cannot broadcast before boot completed");
11569 }
11570 }
11571
11572 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11573 throw new IllegalArgumentException(
11574 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11575 }
11576
11577 return intent;
11578 }
11579
11580 public final int broadcastIntent(IApplicationThread caller,
11581 Intent intent, String resolvedType, IIntentReceiver resultTo,
11582 int resultCode, String resultData, Bundle map,
11583 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011584 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011585 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011587 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11588 final int callingPid = Binder.getCallingPid();
11589 final int callingUid = Binder.getCallingUid();
11590 final long origId = Binder.clearCallingIdentity();
11591 int res = broadcastIntentLocked(callerApp,
11592 callerApp != null ? callerApp.info.packageName : null,
11593 intent, resolvedType, resultTo,
11594 resultCode, resultData, map, requiredPermission, serialized,
11595 sticky, callingPid, callingUid);
11596 Binder.restoreCallingIdentity(origId);
11597 return res;
11598 }
11599 }
11600
11601 int broadcastIntentInPackage(String packageName, int uid,
11602 Intent intent, String resolvedType, IIntentReceiver resultTo,
11603 int resultCode, String resultData, Bundle map,
11604 String requiredPermission, boolean serialized, boolean sticky) {
11605 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011606 intent = verifyBroadcastLocked(intent);
11607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011608 final long origId = Binder.clearCallingIdentity();
11609 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11610 resultTo, resultCode, resultData, map, requiredPermission,
11611 serialized, sticky, -1, uid);
11612 Binder.restoreCallingIdentity(origId);
11613 return res;
11614 }
11615 }
11616
11617 public final void unbroadcastIntent(IApplicationThread caller,
11618 Intent intent) {
11619 // Refuse possible leaked file descriptors
11620 if (intent != null && intent.hasFileDescriptors() == true) {
11621 throw new IllegalArgumentException("File descriptors passed in Intent");
11622 }
11623
11624 synchronized(this) {
11625 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11626 != PackageManager.PERMISSION_GRANTED) {
11627 String msg = "Permission Denial: unbroadcastIntent() from pid="
11628 + Binder.getCallingPid()
11629 + ", uid=" + Binder.getCallingUid()
11630 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011631 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011632 throw new SecurityException(msg);
11633 }
11634 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11635 if (list != null) {
11636 int N = list.size();
11637 int i;
11638 for (i=0; i<N; i++) {
11639 if (intent.filterEquals(list.get(i))) {
11640 list.remove(i);
11641 break;
11642 }
11643 }
11644 }
11645 }
11646 }
11647
11648 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11649 String resultData, Bundle resultExtras, boolean resultAbort,
11650 boolean explicit) {
11651 if (mOrderedBroadcasts.size() == 0) {
11652 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011653 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011654 }
11655 return false;
11656 }
11657 BroadcastRecord r = mOrderedBroadcasts.get(0);
11658 if (r.receiver == null) {
11659 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011660 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011661 }
11662 return false;
11663 }
11664 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011665 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011666 return false;
11667 }
11668 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011669 r.state = BroadcastRecord.IDLE;
11670 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011671 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011672 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011673 }
11674 }
11675 r.receiver = null;
11676 r.intent.setComponent(null);
11677 if (r.curApp != null) {
11678 r.curApp.curReceiver = null;
11679 }
11680 if (r.curFilter != null) {
11681 r.curFilter.receiverList.curBroadcast = null;
11682 }
11683 r.curFilter = null;
11684 r.curApp = null;
11685 r.curComponent = null;
11686 r.curReceiver = null;
11687 mPendingBroadcast = null;
11688
11689 r.resultCode = resultCode;
11690 r.resultData = resultData;
11691 r.resultExtras = resultExtras;
11692 r.resultAbort = resultAbort;
11693
11694 // We will process the next receiver right now if this is finishing
11695 // an app receiver (which is always asynchronous) or after we have
11696 // come back from calling a receiver.
11697 return state == BroadcastRecord.APP_RECEIVE
11698 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11699 }
11700
11701 public void finishReceiver(IBinder who, int resultCode, String resultData,
11702 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011703 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011704
11705 // Refuse possible leaked file descriptors
11706 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11707 throw new IllegalArgumentException("File descriptors passed in Bundle");
11708 }
11709
11710 boolean doNext;
11711
11712 final long origId = Binder.clearCallingIdentity();
11713
11714 synchronized(this) {
11715 doNext = finishReceiverLocked(
11716 who, resultCode, resultData, resultExtras, resultAbort, true);
11717 }
11718
11719 if (doNext) {
11720 processNextBroadcast(false);
11721 }
11722 trimApplications();
11723
11724 Binder.restoreCallingIdentity(origId);
11725 }
11726
Jeff Brown4d94a762010-09-23 11:33:28 -070011727 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011728 if (r.nextReceiver > 0) {
11729 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11730 if (curReceiver instanceof BroadcastFilter) {
11731 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011732 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011733 System.identityHashCode(r),
11734 r.intent.getAction(),
11735 r.nextReceiver - 1,
11736 System.identityHashCode(bf));
11737 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011738 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011739 System.identityHashCode(r),
11740 r.intent.getAction(),
11741 r.nextReceiver - 1,
11742 ((ResolveInfo)curReceiver).toString());
11743 }
11744 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011745 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011746 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011747 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011748 System.identityHashCode(r),
11749 r.intent.getAction(),
11750 r.nextReceiver,
11751 "NONE");
11752 }
11753 }
11754
Jeff Brown4d94a762010-09-23 11:33:28 -070011755 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11756 if (! mPendingBroadcastTimeoutMessage) {
11757 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11758 mHandler.sendMessageAtTime(msg, timeoutTime);
11759 mPendingBroadcastTimeoutMessage = true;
11760 }
11761 }
11762
11763 private final void cancelBroadcastTimeoutLocked() {
11764 if (mPendingBroadcastTimeoutMessage) {
11765 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11766 mPendingBroadcastTimeoutMessage = false;
11767 }
11768 }
11769
11770 private final void broadcastTimeoutLocked(boolean fromMsg) {
11771 if (fromMsg) {
11772 mPendingBroadcastTimeoutMessage = false;
11773 }
11774
11775 if (mOrderedBroadcasts.size() == 0) {
11776 return;
11777 }
11778
11779 long now = SystemClock.uptimeMillis();
11780 BroadcastRecord r = mOrderedBroadcasts.get(0);
11781 if (fromMsg) {
11782 if (mDidDexOpt) {
11783 // Delay timeouts until dexopt finishes.
11784 mDidDexOpt = false;
11785 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11786 setBroadcastTimeoutLocked(timeoutTime);
11787 return;
11788 }
11789 if (! mProcessesReady) {
11790 // Only process broadcast timeouts if the system is ready. That way
11791 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11792 // to do heavy lifting for system up.
11793 return;
11794 }
11795
11796 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11797 if (timeoutTime > now) {
11798 // We can observe premature timeouts because we do not cancel and reset the
11799 // broadcast timeout message after each receiver finishes. Instead, we set up
11800 // an initial timeout then kick it down the road a little further as needed
11801 // when it expires.
11802 if (DEBUG_BROADCAST) Slog.v(TAG,
11803 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11804 + timeoutTime);
11805 setBroadcastTimeoutLocked(timeoutTime);
11806 return;
11807 }
11808 }
11809
11810 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11811 + ", started " + (now - r.receiverTime) + "ms ago");
11812 r.receiverTime = now;
11813 r.anrCount++;
11814
11815 // Current receiver has passed its expiration date.
11816 if (r.nextReceiver <= 0) {
11817 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11818 return;
11819 }
11820
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011821 ProcessRecord app = null;
11822 String anrMessage = null;
11823
Jeff Brown4d94a762010-09-23 11:33:28 -070011824 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11825 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11826 logBroadcastReceiverDiscardLocked(r);
11827 if (curReceiver instanceof BroadcastFilter) {
11828 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11829 if (bf.receiverList.pid != 0
11830 && bf.receiverList.pid != MY_PID) {
11831 synchronized (this.mPidsSelfLocked) {
11832 app = this.mPidsSelfLocked.get(
11833 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011834 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011835 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011836 } else {
11837 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011838 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011839
Jeff Brown4d94a762010-09-23 11:33:28 -070011840 if (app != null) {
11841 anrMessage = "Broadcast of " + r.intent.toString();
11842 }
11843
11844 if (mPendingBroadcast == r) {
11845 mPendingBroadcast = null;
11846 }
11847
11848 // Move on to the next receiver.
11849 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11850 r.resultExtras, r.resultAbort, true);
11851 scheduleBroadcastsLocked();
11852
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011853 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011854 // Post the ANR to the handler since we do not want to process ANRs while
11855 // potentially holding our lock.
11856 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011857 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011858 }
11859
11860 private final void processCurBroadcastLocked(BroadcastRecord r,
11861 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011862 if (DEBUG_BROADCAST) Slog.v(TAG,
11863 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011864 if (app.thread == null) {
11865 throw new RemoteException();
11866 }
11867 r.receiver = app.thread.asBinder();
11868 r.curApp = app;
11869 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011870 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011871
11872 // Tell the application to launch this receiver.
11873 r.intent.setComponent(r.curComponent);
11874
11875 boolean started = false;
11876 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011877 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011878 "Delivering to component " + r.curComponent
11879 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011880 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011881 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011882 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011883 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011884 if (DEBUG_BROADCAST) Slog.v(TAG,
11885 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011886 started = true;
11887 } finally {
11888 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011889 if (DEBUG_BROADCAST) Slog.v(TAG,
11890 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011891 r.receiver = null;
11892 r.curApp = null;
11893 app.curReceiver = null;
11894 }
11895 }
11896
11897 }
11898
Jeff Brown4d94a762010-09-23 11:33:28 -070011899 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011900 Intent intent, int resultCode, String data, Bundle extras,
11901 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011902 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011903 if (app != null && app.thread != null) {
11904 // If we have an app thread, do the call through that so it is
11905 // correctly ordered with other one-way calls.
11906 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011907 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011908 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011909 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011910 }
11911 }
11912
Jeff Brown4d94a762010-09-23 11:33:28 -070011913 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011914 BroadcastFilter filter, boolean ordered) {
11915 boolean skip = false;
11916 if (filter.requiredPermission != null) {
11917 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011918 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011919 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011920 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011921 + r.intent.toString()
11922 + " from " + r.callerPackage + " (pid="
11923 + r.callingPid + ", uid=" + r.callingUid + ")"
11924 + " requires " + filter.requiredPermission
11925 + " due to registered receiver " + filter);
11926 skip = true;
11927 }
11928 }
11929 if (r.requiredPermission != null) {
11930 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011931 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011932 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011933 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011934 + r.intent.toString()
11935 + " to " + filter.receiverList.app
11936 + " (pid=" + filter.receiverList.pid
11937 + ", uid=" + filter.receiverList.uid + ")"
11938 + " requires " + r.requiredPermission
11939 + " due to sender " + r.callerPackage
11940 + " (uid " + r.callingUid + ")");
11941 skip = true;
11942 }
11943 }
11944
11945 if (!skip) {
11946 // If this is not being sent as an ordered broadcast, then we
11947 // don't want to touch the fields that keep track of the current
11948 // state of ordered broadcasts.
11949 if (ordered) {
11950 r.receiver = filter.receiverList.receiver.asBinder();
11951 r.curFilter = filter;
11952 filter.receiverList.curBroadcast = r;
11953 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011954 if (filter.receiverList.app != null) {
11955 // Bump hosting application to no longer be in background
11956 // scheduling class. Note that we can't do that if there
11957 // isn't an app... but we can only be in that case for
11958 // things that directly call the IActivityManager API, which
11959 // are already core system stuff so don't matter for this.
11960 r.curApp = filter.receiverList.app;
11961 filter.receiverList.app.curReceiver = r;
11962 updateOomAdjLocked();
11963 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011964 }
11965 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011966 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011967 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011968 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011969 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011970 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011971 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011972 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011973 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011974 if (ordered) {
11975 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11976 }
11977 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011978 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011979 if (ordered) {
11980 r.receiver = null;
11981 r.curFilter = null;
11982 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011983 if (filter.receiverList.app != null) {
11984 filter.receiverList.app.curReceiver = null;
11985 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011986 }
11987 }
11988 }
11989 }
11990
Dianne Hackborn12527f92009-11-11 17:39:50 -080011991 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11992 if (r.callingUid < 0) {
11993 // This was from a registerReceiver() call; ignore it.
11994 return;
11995 }
11996 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11997 MAX_BROADCAST_HISTORY-1);
11998 r.finishTime = SystemClock.uptimeMillis();
11999 mBroadcastHistory[0] = r;
12000 }
12001
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012002 private final void processNextBroadcast(boolean fromMsg) {
12003 synchronized(this) {
12004 BroadcastRecord r;
12005
Joe Onorato8a9b2202010-02-26 18:56:32 -080012006 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012007 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012008 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012009
12010 updateCpuStats();
12011
12012 if (fromMsg) {
12013 mBroadcastsScheduled = false;
12014 }
12015
12016 // First, deliver any non-serialized broadcasts right away.
12017 while (mParallelBroadcasts.size() > 0) {
12018 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012019 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012020 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012021 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012022 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012023 for (int i=0; i<N; i++) {
12024 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012025 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012026 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012027 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012028 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012029 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012030 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012031 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012032 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012033 }
12034
12035 // Now take care of the next serialized one...
12036
12037 // If we are waiting for a process to come up to handle the next
12038 // broadcast, then do nothing at this point. Just in case, we
12039 // check that the process we're waiting for still exists.
12040 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012041 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012042 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012043 + mPendingBroadcast.curApp);
12044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012045
12046 boolean isDead;
12047 synchronized (mPidsSelfLocked) {
12048 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12049 }
12050 if (!isDead) {
12051 // It's still alive, so keep waiting
12052 return;
12053 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012054 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012055 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012056 mPendingBroadcast.state = BroadcastRecord.IDLE;
12057 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012058 mPendingBroadcast = null;
12059 }
12060 }
12061
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012062 boolean looped = false;
12063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012064 do {
12065 if (mOrderedBroadcasts.size() == 0) {
12066 // No more broadcasts pending, so all done!
12067 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012068 if (looped) {
12069 // If we had finished the last ordered broadcast, then
12070 // make sure all processes have correct oom and sched
12071 // adjustments.
12072 updateOomAdjLocked();
12073 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012074 return;
12075 }
12076 r = mOrderedBroadcasts.get(0);
12077 boolean forceReceive = false;
12078
12079 // Ensure that even if something goes awry with the timeout
12080 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012081 // and continue to make progress.
12082 //
12083 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012084 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012085 // one time heavy lifting after system upgrades and can take
12086 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012087 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012088 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012089 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012090 if ((numReceivers > 0) &&
12091 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012092 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012093 + " now=" + now
12094 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012095 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012096 + " intent=" + r.intent
12097 + " numReceivers=" + numReceivers
12098 + " nextReceiver=" + r.nextReceiver
12099 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012100 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012101 forceReceive = true;
12102 r.state = BroadcastRecord.IDLE;
12103 }
12104 }
12105
12106 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012107 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012108 "processNextBroadcast() called when not idle (state="
12109 + r.state + ")");
12110 return;
12111 }
12112
12113 if (r.receivers == null || r.nextReceiver >= numReceivers
12114 || r.resultAbort || forceReceive) {
12115 // No more receivers for this broadcast! Send the final
12116 // result if requested...
12117 if (r.resultTo != null) {
12118 try {
12119 if (DEBUG_BROADCAST) {
12120 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012121 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012122 + " seq=" + seq + " app=" + r.callerApp);
12123 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012124 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012125 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012126 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012127 // Set this to null so that the reference
12128 // (local and remote) isnt kept in the mBroadcastHistory.
12129 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012130 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012131 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012132 }
12133 }
12134
Joe Onorato8a9b2202010-02-26 18:56:32 -080012135 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012136 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012137
Joe Onorato8a9b2202010-02-26 18:56:32 -080012138 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012139 + r);
12140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012141 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012142 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012143 mOrderedBroadcasts.remove(0);
12144 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012145 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012146 continue;
12147 }
12148 } while (r == null);
12149
12150 // Get the next receiver...
12151 int recIdx = r.nextReceiver++;
12152
12153 // Keep track of when this receiver started, and make sure there
12154 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012155 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012156 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012157 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012158
Joe Onorato8a9b2202010-02-26 18:56:32 -080012159 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012160 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012161 }
12162 if (! mPendingBroadcastTimeoutMessage) {
12163 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012164 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012165 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12166 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012167 }
12168
12169 Object nextReceiver = r.receivers.get(recIdx);
12170 if (nextReceiver instanceof BroadcastFilter) {
12171 // Simple case: this is a registered receiver who gets
12172 // a direct call.
12173 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012174 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012175 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012176 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012177 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012178 if (r.receiver == null || !r.ordered) {
12179 // The receiver has already finished, so schedule to
12180 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012181 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12182 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012183 r.state = BroadcastRecord.IDLE;
12184 scheduleBroadcastsLocked();
12185 }
12186 return;
12187 }
12188
12189 // Hard case: need to instantiate the receiver, possibly
12190 // starting its application process to host it.
12191
12192 ResolveInfo info =
12193 (ResolveInfo)nextReceiver;
12194
12195 boolean skip = false;
12196 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012197 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12198 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012199 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012200 if (!info.activityInfo.exported) {
12201 Slog.w(TAG, "Permission Denial: broadcasting "
12202 + r.intent.toString()
12203 + " from " + r.callerPackage + " (pid=" + r.callingPid
12204 + ", uid=" + r.callingUid + ")"
12205 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12206 + " due to receiver " + info.activityInfo.packageName
12207 + "/" + info.activityInfo.name);
12208 } else {
12209 Slog.w(TAG, "Permission Denial: broadcasting "
12210 + r.intent.toString()
12211 + " from " + r.callerPackage + " (pid=" + r.callingPid
12212 + ", uid=" + r.callingUid + ")"
12213 + " requires " + info.activityInfo.permission
12214 + " due to receiver " + info.activityInfo.packageName
12215 + "/" + info.activityInfo.name);
12216 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012217 skip = true;
12218 }
12219 if (r.callingUid != Process.SYSTEM_UID &&
12220 r.requiredPermission != null) {
12221 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012222 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012223 checkPermission(r.requiredPermission,
12224 info.activityInfo.applicationInfo.packageName);
12225 } catch (RemoteException e) {
12226 perm = PackageManager.PERMISSION_DENIED;
12227 }
12228 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012229 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012230 + r.intent + " to "
12231 + info.activityInfo.applicationInfo.packageName
12232 + " requires " + r.requiredPermission
12233 + " due to sender " + r.callerPackage
12234 + " (uid " + r.callingUid + ")");
12235 skip = true;
12236 }
12237 }
12238 if (r.curApp != null && r.curApp.crashing) {
12239 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012240 if (DEBUG_BROADCAST) Slog.v(TAG,
12241 "Skipping deliver ordered " + r + " to " + r.curApp
12242 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012243 skip = true;
12244 }
12245
12246 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012247 if (DEBUG_BROADCAST) Slog.v(TAG,
12248 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012249 r.receiver = null;
12250 r.curFilter = null;
12251 r.state = BroadcastRecord.IDLE;
12252 scheduleBroadcastsLocked();
12253 return;
12254 }
12255
12256 r.state = BroadcastRecord.APP_RECEIVE;
12257 String targetProcess = info.activityInfo.processName;
12258 r.curComponent = new ComponentName(
12259 info.activityInfo.applicationInfo.packageName,
12260 info.activityInfo.name);
12261 r.curReceiver = info.activityInfo;
12262
Dianne Hackborne7f97212011-02-24 14:40:20 -080012263 // Broadcast is being executed, its package can't be stopped.
12264 try {
12265 AppGlobals.getPackageManager().setPackageStoppedState(
12266 r.curComponent.getPackageName(), false);
12267 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012268 } catch (IllegalArgumentException e) {
12269 Slog.w(TAG, "Failed trying to unstop package "
12270 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012271 }
12272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012273 // Is this receiver's application already running?
12274 ProcessRecord app = getProcessRecordLocked(targetProcess,
12275 info.activityInfo.applicationInfo.uid);
12276 if (app != null && app.thread != null) {
12277 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012278 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012279 processCurBroadcastLocked(r, app);
12280 return;
12281 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012282 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012283 + r.curComponent, e);
12284 }
12285
12286 // If a dead object exception was thrown -- fall through to
12287 // restart the application.
12288 }
12289
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012290 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012291 if (DEBUG_BROADCAST) Slog.v(TAG,
12292 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012293 if ((r.curApp=startProcessLocked(targetProcess,
12294 info.activityInfo.applicationInfo, true,
12295 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012296 "broadcast", r.curComponent,
12297 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12298 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012299 // Ah, this recipient is unavailable. Finish it if necessary,
12300 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012301 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012302 + info.activityInfo.applicationInfo.packageName + "/"
12303 + info.activityInfo.applicationInfo.uid + " for broadcast "
12304 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012305 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012306 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12307 r.resultExtras, r.resultAbort, true);
12308 scheduleBroadcastsLocked();
12309 r.state = BroadcastRecord.IDLE;
12310 return;
12311 }
12312
12313 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012314 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012315 }
12316 }
12317
12318 // =========================================================
12319 // INSTRUMENTATION
12320 // =========================================================
12321
12322 public boolean startInstrumentation(ComponentName className,
12323 String profileFile, int flags, Bundle arguments,
12324 IInstrumentationWatcher watcher) {
12325 // Refuse possible leaked file descriptors
12326 if (arguments != null && arguments.hasFileDescriptors()) {
12327 throw new IllegalArgumentException("File descriptors passed in Bundle");
12328 }
12329
12330 synchronized(this) {
12331 InstrumentationInfo ii = null;
12332 ApplicationInfo ai = null;
12333 try {
12334 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012335 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012336 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012337 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012338 } catch (PackageManager.NameNotFoundException e) {
12339 }
12340 if (ii == null) {
12341 reportStartInstrumentationFailure(watcher, className,
12342 "Unable to find instrumentation info for: " + className);
12343 return false;
12344 }
12345 if (ai == null) {
12346 reportStartInstrumentationFailure(watcher, className,
12347 "Unable to find instrumentation target package: " + ii.targetPackage);
12348 return false;
12349 }
12350
12351 int match = mContext.getPackageManager().checkSignatures(
12352 ii.targetPackage, ii.packageName);
12353 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12354 String msg = "Permission Denial: starting instrumentation "
12355 + className + " from pid="
12356 + Binder.getCallingPid()
12357 + ", uid=" + Binder.getCallingPid()
12358 + " not allowed because package " + ii.packageName
12359 + " does not have a signature matching the target "
12360 + ii.targetPackage;
12361 reportStartInstrumentationFailure(watcher, className, msg);
12362 throw new SecurityException(msg);
12363 }
12364
12365 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012366 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012367 ProcessRecord app = addAppLocked(ai);
12368 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012369 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012370 app.instrumentationProfileFile = profileFile;
12371 app.instrumentationArguments = arguments;
12372 app.instrumentationWatcher = watcher;
12373 app.instrumentationResultClass = className;
12374 Binder.restoreCallingIdentity(origId);
12375 }
12376
12377 return true;
12378 }
12379
12380 /**
12381 * Report errors that occur while attempting to start Instrumentation. Always writes the
12382 * error to the logs, but if somebody is watching, send the report there too. This enables
12383 * the "am" command to report errors with more information.
12384 *
12385 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12386 * @param cn The component name of the instrumentation.
12387 * @param report The error report.
12388 */
12389 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12390 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012391 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012392 try {
12393 if (watcher != null) {
12394 Bundle results = new Bundle();
12395 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12396 results.putString("Error", report);
12397 watcher.instrumentationStatus(cn, -1, results);
12398 }
12399 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012400 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012401 }
12402 }
12403
12404 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12405 if (app.instrumentationWatcher != null) {
12406 try {
12407 // NOTE: IInstrumentationWatcher *must* be oneway here
12408 app.instrumentationWatcher.instrumentationFinished(
12409 app.instrumentationClass,
12410 resultCode,
12411 results);
12412 } catch (RemoteException e) {
12413 }
12414 }
12415 app.instrumentationWatcher = null;
12416 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012417 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012418 app.instrumentationProfileFile = null;
12419 app.instrumentationArguments = null;
12420
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012421 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012422 }
12423
12424 public void finishInstrumentation(IApplicationThread target,
12425 int resultCode, Bundle results) {
12426 // Refuse possible leaked file descriptors
12427 if (results != null && results.hasFileDescriptors()) {
12428 throw new IllegalArgumentException("File descriptors passed in Intent");
12429 }
12430
12431 synchronized(this) {
12432 ProcessRecord app = getRecordForAppLocked(target);
12433 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012434 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012435 return;
12436 }
12437 final long origId = Binder.clearCallingIdentity();
12438 finishInstrumentationLocked(app, resultCode, results);
12439 Binder.restoreCallingIdentity(origId);
12440 }
12441 }
12442
12443 // =========================================================
12444 // CONFIGURATION
12445 // =========================================================
12446
12447 public ConfigurationInfo getDeviceConfigurationInfo() {
12448 ConfigurationInfo config = new ConfigurationInfo();
12449 synchronized (this) {
12450 config.reqTouchScreen = mConfiguration.touchscreen;
12451 config.reqKeyboardType = mConfiguration.keyboard;
12452 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012453 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12454 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012455 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12456 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012457 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12458 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012459 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12460 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012461 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012462 }
12463 return config;
12464 }
12465
12466 public Configuration getConfiguration() {
12467 Configuration ci;
12468 synchronized(this) {
12469 ci = new Configuration(mConfiguration);
12470 }
12471 return ci;
12472 }
12473
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012474 public void updatePersistentConfiguration(Configuration values) {
12475 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12476 "updateConfiguration()");
12477 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12478 "updateConfiguration()");
12479 if (values == null) {
12480 throw new NullPointerException("Configuration must not be null");
12481 }
12482
12483 synchronized(this) {
12484 final long origId = Binder.clearCallingIdentity();
12485 updateConfigurationLocked(values, null, true);
12486 Binder.restoreCallingIdentity(origId);
12487 }
12488 }
12489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012490 public void updateConfiguration(Configuration values) {
12491 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12492 "updateConfiguration()");
12493
12494 synchronized(this) {
12495 if (values == null && mWindowManager != null) {
12496 // sentinel: fetch the current configuration from the window manager
12497 values = mWindowManager.computeNewConfiguration();
12498 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012499
12500 if (mWindowManager != null) {
12501 mProcessList.applyDisplaySize(mWindowManager);
12502 }
12503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012504 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012505 if (values != null) {
12506 Settings.System.clearConfiguration(values);
12507 }
12508 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012509 Binder.restoreCallingIdentity(origId);
12510 }
12511 }
12512
12513 /**
12514 * Do either or both things: (1) change the current configuration, and (2)
12515 * make sure the given activity is running with the (now) current
12516 * configuration. Returns true if the activity has been left running, or
12517 * false if <var>starting</var> is being destroyed to match the new
12518 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012519 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012520 */
12521 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012522 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012523 int changes = 0;
12524
12525 boolean kept = true;
12526
12527 if (values != null) {
12528 Configuration newConfig = new Configuration(mConfiguration);
12529 changes = newConfig.updateFrom(values);
12530 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012531 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012532 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012533 }
12534
Doug Zongker2bec3d42009-12-04 12:52:44 -080012535 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012536
12537 if (values.locale != null) {
12538 saveLocaleLocked(values.locale,
12539 !values.locale.equals(mConfiguration.locale),
12540 values.userSetLocale);
12541 }
12542
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012543 mConfigurationSeq++;
12544 if (mConfigurationSeq <= 0) {
12545 mConfigurationSeq = 1;
12546 }
12547 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012548 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012549 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012550
12551 AttributeCache ac = AttributeCache.instance();
12552 if (ac != null) {
12553 ac.updateConfiguration(mConfiguration);
12554 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012555
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012556 // Make sure all resources in our process are updated
12557 // right now, so that anyone who is going to retrieve
12558 // resource values after we return will be sure to get
12559 // the new ones. This is especially important during
12560 // boot, where the first config change needs to guarantee
12561 // all resources have that config before following boot
12562 // code is executed.
12563 mSystemThread.applyConfigurationToResources(newConfig);
12564
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012565 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012566 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12567 msg.obj = new Configuration(mConfiguration);
12568 mHandler.sendMessage(msg);
12569 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012570
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012571 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12572 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012573 try {
12574 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012575 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012576 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012577 app.thread.scheduleConfigurationChanged(mConfiguration);
12578 }
12579 } catch (Exception e) {
12580 }
12581 }
12582 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012583 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12584 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012585 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12586 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012587 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12588 broadcastIntentLocked(null, null,
12589 new Intent(Intent.ACTION_LOCALE_CHANGED),
12590 null, null, 0, null, null,
12591 null, false, false, MY_PID, Process.SYSTEM_UID);
12592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012593 }
12594 }
12595
12596 if (changes != 0 && starting == null) {
12597 // If the configuration changed, and the caller is not already
12598 // in the process of starting an activity, then find the top
12599 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012600 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012601 }
12602
12603 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012604 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012605 // And we need to make sure at this point that all other activities
12606 // are made visible with the correct configuration.
12607 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012608 }
12609
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012610 if (values != null && mWindowManager != null) {
12611 mWindowManager.setNewConfiguration(mConfiguration);
12612 }
12613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012614 return kept;
12615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012616
12617 /**
12618 * Save the locale. You must be inside a synchronized (this) block.
12619 */
12620 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12621 if(isDiff) {
12622 SystemProperties.set("user.language", l.getLanguage());
12623 SystemProperties.set("user.region", l.getCountry());
12624 }
12625
12626 if(isPersist) {
12627 SystemProperties.set("persist.sys.language", l.getLanguage());
12628 SystemProperties.set("persist.sys.country", l.getCountry());
12629 SystemProperties.set("persist.sys.localevar", l.getVariant());
12630 }
12631 }
12632
12633 // =========================================================
12634 // LIFETIME MANAGEMENT
12635 // =========================================================
12636
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012637 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12638 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012639 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012640 // This adjustment has already been computed. If we are calling
12641 // from the top, we may have already computed our adjustment with
12642 // an earlier hidden adjustment that isn't really for us... if
12643 // so, use the new hidden adjustment.
12644 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012645 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012646 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012647 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012648 }
12649
12650 if (app.thread == null) {
12651 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012652 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012653 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012654 }
12655
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012656 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12657 app.adjSource = null;
12658 app.adjTarget = null;
12659 app.empty = false;
12660 app.hidden = false;
12661
12662 final int activitiesSize = app.activities.size();
12663
Dianne Hackborn7d608422011-08-07 16:24:18 -070012664 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012665 // The max adjustment doesn't allow this app to be anything
12666 // below foreground, so it is not worth doing work for it.
12667 app.adjType = "fixed";
12668 app.adjSeq = mAdjSeq;
12669 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012670 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012671 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012672 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012673 // System process can do UI, and when they do we want to have
12674 // them trim their memory after the user leaves the UI. To
12675 // facilitate this, here we need to determine whether or not it
12676 // is currently showing UI.
12677 app.systemNoUi = true;
12678 if (app == TOP_APP) {
12679 app.systemNoUi = false;
12680 } else if (activitiesSize > 0) {
12681 for (int j = 0; j < activitiesSize; j++) {
12682 final ActivityRecord r = app.activities.get(j);
12683 if (r.visible) {
12684 app.systemNoUi = false;
12685 break;
12686 }
12687 }
12688 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012689 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012690 }
12691
12692 final boolean hadForegroundActivities = app.foregroundActivities;
12693
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012694 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012695 app.keeping = false;
12696 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012697
The Android Open Source Project4df24232009-03-05 14:34:35 -080012698 // Determine the importance of the process, starting with most
12699 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012700 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012701 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012702 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012703 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012704 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012705 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012706 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012707 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012708 } else if (app.instrumentationClass != null) {
12709 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012710 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012711 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012712 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012713 } else if (app.curReceiver != null ||
12714 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12715 // An app that is currently receiving a broadcast also
12716 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012717 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012718 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012719 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012720 } else if (app.executingServices.size() > 0) {
12721 // An app that is currently executing a service callback also
12722 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012723 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012724 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012725 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012726 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012727 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012728 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012729 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012730 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012731 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012732 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012733 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012734 // A very not-needed process. If this is lower in the lru list,
12735 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012736 adj = hiddenAdj;
12737 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012738 app.hidden = true;
12739 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012740 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012741 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012742
12743 // Examine all activities if not already foreground.
12744 if (!app.foregroundActivities && activitiesSize > 0) {
12745 for (int j = 0; j < activitiesSize; j++) {
12746 final ActivityRecord r = app.activities.get(j);
12747 if (r.visible) {
12748 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012749 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12750 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012751 app.adjType = "visible";
12752 }
12753 schedGroup = Process.THREAD_GROUP_DEFAULT;
12754 app.hidden = false;
12755 app.foregroundActivities = true;
12756 break;
12757 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12758 || r.state == ActivityState.STOPPING) {
12759 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012760 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12761 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012762 app.adjType = "stopping";
12763 }
12764 app.foregroundActivities = true;
12765 }
12766 }
12767 }
12768
Dianne Hackborn7d608422011-08-07 16:24:18 -070012769 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012770 if (app.foregroundServices) {
12771 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012772 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012773 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012774 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012775 } else if (app.forcingToForeground != null) {
12776 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012777 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012778 app.adjType = "force-foreground";
12779 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012780 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012781 }
12782 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012783
Dianne Hackborn7d608422011-08-07 16:24:18 -070012784 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012785 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012786 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012787 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12788 app.adjType = "heavy";
12789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012790
Dianne Hackborn7d608422011-08-07 16:24:18 -070012791 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012792 // This process is hosting what we currently consider to be the
12793 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012794 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012795 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12796 app.adjType = "home";
12797 }
12798
Joe Onorato8a9b2202010-02-26 18:56:32 -080012799 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012800
The Android Open Source Project4df24232009-03-05 14:34:35 -080012801 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012802 // there are applications dependent on our services or providers, but
12803 // this gives us a baseline and makes sure we don't get into an
12804 // infinite recursion.
12805 app.adjSeq = mAdjSeq;
12806 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012807
Christopher Tate6fa95972009-06-05 18:43:55 -070012808 if (mBackupTarget != null && app == mBackupTarget.app) {
12809 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070012810 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012811 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070012812 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012813 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012814 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012815 }
12816 }
12817
Dianne Hackborn7d608422011-08-07 16:24:18 -070012818 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012819 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012820 final long now = SystemClock.uptimeMillis();
12821 // This process is more important if the top activity is
12822 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012823 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012824 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012825 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012826 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012827 if (app.hasShownUi) {
12828 // If this process has shown some UI, let it immediately
12829 // go to the LRU list because it may be pretty heavy with
12830 // UI stuff. We'll tag it with a label just to help
12831 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012832 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012833 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012834 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012835 } else {
12836 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12837 // This service has seen some activity within
12838 // recent memory, so we will keep its process ahead
12839 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012840 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
12841 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012842 app.adjType = "started-services";
12843 app.hidden = false;
12844 }
12845 }
12846 // If we have let the service slide into the background
12847 // state, still have some text describing what it is doing
12848 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012849 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012850 app.adjType = "started-bg-services";
12851 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012852 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012853 // Don't kill this process because it is doing work; it
12854 // has said it is doing work.
12855 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012856 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012857 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012858 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012859 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012860 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012861 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012862 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012863 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012864 // XXX should compute this based on the max of
12865 // all connected clients.
12866 ConnectionRecord cr = clist.get(i);
12867 if (cr.binding.client == app) {
12868 // Binding to ourself is not interesting.
12869 continue;
12870 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012871 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012872 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012873 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012874 int myHiddenAdj = hiddenAdj;
12875 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012876 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012877 myHiddenAdj = client.hiddenAdj;
12878 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012879 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012880 }
12881 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012882 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012883 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012884 String adjType = null;
12885 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12886 // Not doing bind OOM management, so treat
12887 // this guy more like a started service.
12888 if (app.hasShownUi) {
12889 // If this process has shown some UI, let it immediately
12890 // go to the LRU list because it may be pretty heavy with
12891 // UI stuff. We'll tag it with a label just to help
12892 // debug and understand what is going on.
12893 if (adj > clientAdj) {
12894 adjType = "bound-bg-ui-services";
12895 }
12896 clientAdj = adj;
12897 } else {
12898 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12899 // This service has not seen activity within
12900 // recent memory, so allow it to drop to the
12901 // LRU list if there is no other reason to keep
12902 // it around. We'll also tag it with a label just
12903 // to help debug and undertand what is going on.
12904 if (adj > clientAdj) {
12905 adjType = "bound-bg-services";
12906 }
12907 clientAdj = adj;
12908 }
12909 }
12910 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012911 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012912 // If this process has recently shown UI, and
12913 // the process that is binding to it is less
12914 // important than being visible, then we don't
12915 // care about the binding as much as we care
12916 // about letting this process get into the LRU
12917 // list to be killed and restarted if needed for
12918 // memory.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012919 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012920 adjType = "bound-bg-ui-services";
12921 } else {
12922 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12923 |Context.BIND_IMPORTANT)) != 0) {
12924 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012925 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012926 adj = clientAdj;
12927 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012928 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012929 }
12930 if (!client.hidden) {
12931 app.hidden = false;
12932 }
12933 if (client.keeping) {
12934 app.keeping = true;
12935 }
12936 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012937 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012938 }
12939 if (adjType != null) {
12940 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012941 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12942 .REASON_SERVICE_IN_USE;
12943 app.adjSource = cr.binding.client;
12944 app.adjTarget = s.name;
12945 }
12946 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12947 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12948 schedGroup = Process.THREAD_GROUP_DEFAULT;
12949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012950 }
12951 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012952 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12953 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012954 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012955 (a.visible || a.state == ActivityState.RESUMED
12956 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012957 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012958 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12959 schedGroup = Process.THREAD_GROUP_DEFAULT;
12960 }
12961 app.hidden = false;
12962 app.adjType = "service";
12963 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12964 .REASON_SERVICE_IN_USE;
12965 app.adjSource = a;
12966 app.adjTarget = s.name;
12967 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012968 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012969 }
12970 }
12971 }
12972 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012973
Dianne Hackborn287952c2010-09-22 22:34:31 -070012974 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012975 // would like to avoid killing it unless it would prevent the current
12976 // application from running. By default we put the process in
12977 // with the rest of the background processes; as we scan through
12978 // its services we may bump it up from there.
12979 if (adj > hiddenAdj) {
12980 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012981 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012982 app.adjType = "bg-services";
12983 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012984 }
12985
Dianne Hackborn7d608422011-08-07 16:24:18 -070012986 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012987 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012988 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012989 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012990 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012991 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012992 if (cpr.clients.size() != 0) {
12993 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012994 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012995 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012996 if (client == app) {
12997 // Being our own client is not interesting.
12998 continue;
12999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013000 int myHiddenAdj = hiddenAdj;
13001 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013002 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013003 myHiddenAdj = client.hiddenAdj;
13004 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013005 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013006 }
13007 }
13008 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013009 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013010 if (adj > clientAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013011 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013012 app.adjType = "bg-ui-provider";
13013 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013014 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13015 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013016 app.adjType = "provider";
13017 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013018 if (!client.hidden) {
13019 app.hidden = false;
13020 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013021 if (client.keeping) {
13022 app.keeping = true;
13023 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013024 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13025 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013026 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013027 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013028 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013029 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13030 schedGroup = Process.THREAD_GROUP_DEFAULT;
13031 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013032 }
13033 }
13034 // If the provider has external (non-framework) process
13035 // dependencies, ensure that its adjustment is at least
13036 // FOREGROUND_APP_ADJ.
13037 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013038 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13039 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013040 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013041 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013042 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013043 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013044 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013045 }
13046 }
13047 }
13048 }
13049
13050 app.curRawAdj = adj;
13051
Joe Onorato8a9b2202010-02-26 18:56:32 -080013052 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013053 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13054 if (adj > app.maxAdj) {
13055 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013056 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013057 schedGroup = Process.THREAD_GROUP_DEFAULT;
13058 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013059 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013060 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013061 app.keeping = true;
13062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013063
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013064 if (app.hasAboveClient) {
13065 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13066 // then we need to drop its adjustment to be lower than the service's
13067 // in order to honor the request. We want to drop it by one adjustment
13068 // level... but there is special meaning applied to various levels so
13069 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013070 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013071 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013072 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13073 adj = ProcessList.VISIBLE_APP_ADJ;
13074 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13075 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13076 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13077 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13078 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013079 adj++;
13080 }
13081 }
13082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013083 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013084 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013085
13086 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013087 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13088 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013089 }
13090
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013091 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013092 }
13093
13094 /**
13095 * Ask a given process to GC right now.
13096 */
13097 final void performAppGcLocked(ProcessRecord app) {
13098 try {
13099 app.lastRequestedGc = SystemClock.uptimeMillis();
13100 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013101 if (app.reportLowMemory) {
13102 app.reportLowMemory = false;
13103 app.thread.scheduleLowMemory();
13104 } else {
13105 app.thread.processInBackground();
13106 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013107 }
13108 } catch (Exception e) {
13109 // whatever.
13110 }
13111 }
13112
13113 /**
13114 * Returns true if things are idle enough to perform GCs.
13115 */
Josh Bartel7f208742010-02-25 11:01:44 -060013116 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013117 return mParallelBroadcasts.size() == 0
13118 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013119 && (mSleeping || (mMainStack.mResumedActivity != null &&
13120 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013121 }
13122
13123 /**
13124 * Perform GCs on all processes that are waiting for it, but only
13125 * if things are idle.
13126 */
13127 final void performAppGcsLocked() {
13128 final int N = mProcessesToGc.size();
13129 if (N <= 0) {
13130 return;
13131 }
Josh Bartel7f208742010-02-25 11:01:44 -060013132 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013133 while (mProcessesToGc.size() > 0) {
13134 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013135 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013136 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13137 <= SystemClock.uptimeMillis()) {
13138 // To avoid spamming the system, we will GC processes one
13139 // at a time, waiting a few seconds between each.
13140 performAppGcLocked(proc);
13141 scheduleAppGcsLocked();
13142 return;
13143 } else {
13144 // It hasn't been long enough since we last GCed this
13145 // process... put it in the list to wait for its time.
13146 addProcessToGcListLocked(proc);
13147 break;
13148 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013149 }
13150 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013151
13152 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013153 }
13154 }
13155
13156 /**
13157 * If all looks good, perform GCs on all processes waiting for them.
13158 */
13159 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013160 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013161 performAppGcsLocked();
13162 return;
13163 }
13164 // Still not idle, wait some more.
13165 scheduleAppGcsLocked();
13166 }
13167
13168 /**
13169 * Schedule the execution of all pending app GCs.
13170 */
13171 final void scheduleAppGcsLocked() {
13172 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013173
13174 if (mProcessesToGc.size() > 0) {
13175 // Schedule a GC for the time to the next process.
13176 ProcessRecord proc = mProcessesToGc.get(0);
13177 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13178
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013179 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013180 long now = SystemClock.uptimeMillis();
13181 if (when < (now+GC_TIMEOUT)) {
13182 when = now + GC_TIMEOUT;
13183 }
13184 mHandler.sendMessageAtTime(msg, when);
13185 }
13186 }
13187
13188 /**
13189 * Add a process to the array of processes waiting to be GCed. Keeps the
13190 * list in sorted order by the last GC time. The process can't already be
13191 * on the list.
13192 */
13193 final void addProcessToGcListLocked(ProcessRecord proc) {
13194 boolean added = false;
13195 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13196 if (mProcessesToGc.get(i).lastRequestedGc <
13197 proc.lastRequestedGc) {
13198 added = true;
13199 mProcessesToGc.add(i+1, proc);
13200 break;
13201 }
13202 }
13203 if (!added) {
13204 mProcessesToGc.add(0, proc);
13205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013206 }
13207
13208 /**
13209 * Set up to ask a process to GC itself. This will either do it
13210 * immediately, or put it on the list of processes to gc the next
13211 * time things are idle.
13212 */
13213 final void scheduleAppGcLocked(ProcessRecord app) {
13214 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013215 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013216 return;
13217 }
13218 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013219 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013220 scheduleAppGcsLocked();
13221 }
13222 }
13223
Dianne Hackborn287952c2010-09-22 22:34:31 -070013224 final void checkExcessivePowerUsageLocked(boolean doKills) {
13225 updateCpuStatsNow();
13226
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013227 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013228 boolean doWakeKills = doKills;
13229 boolean doCpuKills = doKills;
13230 if (mLastPowerCheckRealtime == 0) {
13231 doWakeKills = false;
13232 }
13233 if (mLastPowerCheckUptime == 0) {
13234 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013235 }
13236 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013237 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013238 }
13239 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013240 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13241 final long curUptime = SystemClock.uptimeMillis();
13242 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13243 mLastPowerCheckRealtime = curRealtime;
13244 mLastPowerCheckUptime = curUptime;
13245 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13246 doWakeKills = false;
13247 }
13248 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13249 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013250 }
13251 int i = mLruProcesses.size();
13252 while (i > 0) {
13253 i--;
13254 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013255 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013256 long wtime;
13257 synchronized (stats) {
13258 wtime = stats.getProcessWakeTime(app.info.uid,
13259 app.pid, curRealtime);
13260 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013261 long wtimeUsed = wtime - app.lastWakeTime;
13262 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13263 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013264 StringBuilder sb = new StringBuilder(128);
13265 sb.append("Wake for ");
13266 app.toShortString(sb);
13267 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013268 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013269 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013270 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013271 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013272 sb.append((wtimeUsed*100)/realtimeSince);
13273 sb.append("%)");
13274 Slog.i(TAG, sb.toString());
13275 sb.setLength(0);
13276 sb.append("CPU for ");
13277 app.toShortString(sb);
13278 sb.append(": over ");
13279 TimeUtils.formatDuration(uptimeSince, sb);
13280 sb.append(" used ");
13281 TimeUtils.formatDuration(cputimeUsed, sb);
13282 sb.append(" (");
13283 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013284 sb.append("%)");
13285 Slog.i(TAG, sb.toString());
13286 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013287 // If a process has held a wake lock for more
13288 // than 50% of the time during this period,
13289 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013290 if (doWakeKills && realtimeSince > 0
13291 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13292 synchronized (stats) {
13293 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13294 realtimeSince, wtimeUsed);
13295 }
13296 Slog.w(TAG, "Excessive wake lock in " + app.processName
13297 + " (pid " + app.pid + "): held " + wtimeUsed
13298 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013299 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13300 app.processName, app.setAdj, "excessive wake lock");
13301 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013302 } else if (doCpuKills && uptimeSince > 0
13303 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13304 synchronized (stats) {
13305 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13306 uptimeSince, cputimeUsed);
13307 }
13308 Slog.w(TAG, "Excessive CPU in " + app.processName
13309 + " (pid " + app.pid + "): used " + cputimeUsed
13310 + " during " + uptimeSince);
13311 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13312 app.processName, app.setAdj, "excessive cpu");
13313 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013314 } else {
13315 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013316 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013317 }
13318 }
13319 }
13320 }
13321
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013322 private final void updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013323 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013324 app.hiddenAdj = hiddenAdj;
13325
13326 if (app.thread == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013327 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013328 }
13329
Dianne Hackborn287952c2010-09-22 22:34:31 -070013330 final boolean wasKeeping = app.keeping;
13331
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013332 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013333
Jeff Brown10e89712011-07-08 18:52:57 -070013334 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013335 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13336 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013337 // If this app is transitioning from foreground to
13338 // non-foreground, have it do a gc.
13339 scheduleAppGcLocked(app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013340 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13341 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013342 // Likewise do a gc when an app is moving in to the
13343 // background (such as a service stopping).
13344 scheduleAppGcLocked(app);
13345 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013346
Jeff Brown10e89712011-07-08 18:52:57 -070013347 if (wasKeeping && !app.keeping) {
13348 // This app is no longer something we want to keep. Note
13349 // its current wake lock time to later know to kill it if
13350 // it is not behaving well.
13351 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13352 synchronized (stats) {
13353 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13354 app.pid, SystemClock.elapsedRealtime());
13355 }
13356 app.lastCpuTime = app.curCpuTime;
13357 }
13358
13359 app.setRawAdj = app.curRawAdj;
13360 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013361 if (app.curAdj != app.setAdj) {
13362 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013363 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13364 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013365 " oom adj to " + app.curAdj + " because " + app.adjType);
13366 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013367 } else {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013368 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013369 }
13370 }
13371 if (app.setSchedGroup != app.curSchedGroup) {
13372 app.setSchedGroup = app.curSchedGroup;
13373 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13374 "Setting process group of " + app.processName
13375 + " to " + app.curSchedGroup);
13376 if (app.waitingToKill != null &&
13377 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13378 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13379 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13380 app.processName, app.setAdj, app.waitingToKill);
13381 Process.killProcessQuiet(app.pid);
13382 } else {
13383 if (true) {
13384 long oldId = Binder.clearCallingIdentity();
13385 try {
13386 Process.setProcessGroup(app.pid, app.curSchedGroup);
13387 } catch (Exception e) {
13388 Slog.w(TAG, "Failed setting process group of " + app.pid
13389 + " to " + app.curSchedGroup);
13390 e.printStackTrace();
13391 } finally {
13392 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013393 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013394 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013395 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013396 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013397 app.thread.setSchedulingGroup(app.curSchedGroup);
13398 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013399 }
13400 }
13401 }
13402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013403 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013404 }
13405
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013406 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013407 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013408 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013409 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013410 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013411 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013412 }
13413 }
13414 return resumedActivity;
13415 }
13416
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013417 private final void updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013418 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013419 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13420 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013421 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13422 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013423
13424 mAdjSeq++;
13425
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013426 updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013427 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13428 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013429 if (nowHidden != wasHidden) {
13430 // Changed to/from hidden state, so apps after it in the LRU
13431 // list may also be changed.
13432 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013434 }
13435
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013436 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013437 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013438 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13439
13440 if (false) {
13441 RuntimeException e = new RuntimeException();
13442 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013443 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013444 }
13445
13446 mAdjSeq++;
13447
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013448 // Let's determine how many processes we have running vs.
13449 // how many slots we have for background processes; we may want
13450 // to put multiple processes in a slot of there are enough of
13451 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013452 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013453 int factor = (mLruProcesses.size()-4)/numSlots;
13454 if (factor < 1) factor = 1;
13455 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013456 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013457
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013458 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013459 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013460 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013461 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013462 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013463 while (i > 0) {
13464 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013465 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013466 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013467 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013468 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013469 && app.curAdj == curHiddenAdj) {
13470 step++;
13471 if (step >= factor) {
13472 step = 0;
13473 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013474 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013475 }
13476 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013477 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013478 numHidden++;
13479 if (numHidden > mProcessLimit) {
13480 Slog.i(TAG, "No longer want " + app.processName
13481 + " (pid " + app.pid + "): hidden #" + numHidden);
13482 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13483 app.processName, app.setAdj, "too many background");
13484 app.killedBackground = true;
13485 Process.killProcessQuiet(app.pid);
13486 } else {
13487 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013488 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013489 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013490 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013492 }
13493 }
13494
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013495 // Now determine the memory trimming level of background processes.
13496 // Unfortunately we need to start at the back of the list to do this
13497 // properly. We only do this if the number of background apps we
13498 // are managing to keep around is less than half the maximum we desire;
13499 // if we are keeping a good number around, we'll let them use whatever
13500 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013501 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013502 final int N = mLruProcesses.size();
13503 factor = numBg/3;
13504 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013505 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013506 for (i=0; i<N; i++) {
13507 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013508 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013509 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13510 try {
13511 app.thread.scheduleTrimMemory(curLevel);
13512 } catch (RemoteException e) {
13513 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013514 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013515 // For these apps we will also finish their activities
13516 // to help them free memory.
13517 mMainStack.destroyActivitiesLocked(app, false);
13518 }
13519 }
13520 app.trimMemoryLevel = curLevel;
13521 step++;
13522 if (step >= factor) {
13523 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013524 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13525 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013526 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013527 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13528 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013529 break;
13530 }
13531 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013532 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013533 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013534 && app.thread != null) {
13535 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013536 app.thread.scheduleTrimMemory(
13537 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013538 } catch (RemoteException e) {
13539 }
13540 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013541 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013542 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013543 && app.pendingUiClean) {
13544 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13545 && app.thread != null) {
13546 try {
13547 app.thread.scheduleTrimMemory(
13548 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13549 } catch (RemoteException e) {
13550 }
13551 }
13552 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13553 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013554 } else {
13555 app.trimMemoryLevel = 0;
13556 }
13557 }
13558 } else {
13559 final int N = mLruProcesses.size();
13560 for (i=0; i<N; i++) {
13561 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013562 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013563 && app.pendingUiClean) {
13564 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13565 && app.thread != null) {
13566 try {
13567 app.thread.scheduleTrimMemory(
13568 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13569 } catch (RemoteException e) {
13570 }
13571 }
13572 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13573 app.pendingUiClean = false;
13574 } else {
13575 app.trimMemoryLevel = 0;
13576 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013577 }
13578 }
13579
13580 if (mAlwaysFinishActivities) {
13581 mMainStack.destroyActivitiesLocked(null, false);
13582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013583 }
13584
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013585 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013586 synchronized (this) {
13587 int i;
13588
13589 // First remove any unused application processes whose package
13590 // has been removed.
13591 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13592 final ProcessRecord app = mRemovedProcesses.get(i);
13593 if (app.activities.size() == 0
13594 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013595 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013596 TAG, "Exiting empty application process "
13597 + app.processName + " ("
13598 + (app.thread != null ? app.thread.asBinder() : null)
13599 + ")\n");
13600 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013601 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13602 app.processName, app.setAdj, "empty");
13603 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013604 } else {
13605 try {
13606 app.thread.scheduleExit();
13607 } catch (Exception e) {
13608 // Ignore exceptions.
13609 }
13610 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013611 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013612 mRemovedProcesses.remove(i);
13613
13614 if (app.persistent) {
13615 if (app.persistent) {
13616 addAppLocked(app.info);
13617 }
13618 }
13619 }
13620 }
13621
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013622 // Now update the oom adj for all processes.
13623 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013624 }
13625 }
13626
13627 /** This method sends the specified signal to each of the persistent apps */
13628 public void signalPersistentProcesses(int sig) throws RemoteException {
13629 if (sig != Process.SIGNAL_USR1) {
13630 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13631 }
13632
13633 synchronized (this) {
13634 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13635 != PackageManager.PERMISSION_GRANTED) {
13636 throw new SecurityException("Requires permission "
13637 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13638 }
13639
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013640 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13641 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013642 if (r.thread != null && r.persistent) {
13643 Process.sendSignal(r.pid, sig);
13644 }
13645 }
13646 }
13647 }
13648
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013649 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13650 if (proc == null || proc == mProfileProc) {
13651 proc = mProfileProc;
13652 path = mProfileFile;
13653 profileType = mProfileType;
13654 clearProfilerLocked();
13655 }
13656 if (proc == null) {
13657 return;
13658 }
13659 try {
13660 proc.thread.profilerControl(false, path, null, profileType);
13661 } catch (RemoteException e) {
13662 throw new IllegalStateException("Process disappeared");
13663 }
13664 }
13665
13666 private void clearProfilerLocked() {
13667 if (mProfileFd != null) {
13668 try {
13669 mProfileFd.close();
13670 } catch (IOException e) {
13671 }
13672 }
13673 mProfileApp = null;
13674 mProfileProc = null;
13675 mProfileFile = null;
13676 mProfileType = 0;
13677 mAutoStopProfiler = false;
13678 }
13679
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013680 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013681 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013682
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013683 try {
13684 synchronized (this) {
13685 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13686 // its own permission.
13687 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13688 != PackageManager.PERMISSION_GRANTED) {
13689 throw new SecurityException("Requires permission "
13690 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013691 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013692
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013693 if (start && fd == null) {
13694 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013695 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013696
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013697 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013698 if (process != null) {
13699 try {
13700 int pid = Integer.parseInt(process);
13701 synchronized (mPidsSelfLocked) {
13702 proc = mPidsSelfLocked.get(pid);
13703 }
13704 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013705 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013706
13707 if (proc == null) {
13708 HashMap<String, SparseArray<ProcessRecord>> all
13709 = mProcessNames.getMap();
13710 SparseArray<ProcessRecord> procs = all.get(process);
13711 if (procs != null && procs.size() > 0) {
13712 proc = procs.valueAt(0);
13713 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013714 }
13715 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013716
13717 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013718 throw new IllegalArgumentException("Unknown process: " + process);
13719 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013720
13721 if (start) {
13722 stopProfilerLocked(null, null, 0);
13723 setProfileApp(proc.info, proc.processName, path, fd, false);
13724 mProfileProc = proc;
13725 mProfileType = profileType;
13726 try {
13727 fd = fd.dup();
13728 } catch (IOException e) {
13729 fd = null;
13730 }
13731 proc.thread.profilerControl(start, path, fd, profileType);
13732 fd = null;
13733 mProfileFd = null;
13734 } else {
13735 stopProfilerLocked(proc, path, profileType);
13736 if (fd != null) {
13737 try {
13738 fd.close();
13739 } catch (IOException e) {
13740 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013741 }
13742 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013743
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013744 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013745 }
13746 } catch (RemoteException e) {
13747 throw new IllegalStateException("Process disappeared");
13748 } finally {
13749 if (fd != null) {
13750 try {
13751 fd.close();
13752 } catch (IOException e) {
13753 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013754 }
13755 }
13756 }
Andy McFadden824c5102010-07-09 16:26:57 -070013757
13758 public boolean dumpHeap(String process, boolean managed,
13759 String path, ParcelFileDescriptor fd) throws RemoteException {
13760
13761 try {
13762 synchronized (this) {
13763 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13764 // its own permission (same as profileControl).
13765 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13766 != PackageManager.PERMISSION_GRANTED) {
13767 throw new SecurityException("Requires permission "
13768 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13769 }
13770
13771 if (fd == null) {
13772 throw new IllegalArgumentException("null fd");
13773 }
13774
13775 ProcessRecord proc = null;
13776 try {
13777 int pid = Integer.parseInt(process);
13778 synchronized (mPidsSelfLocked) {
13779 proc = mPidsSelfLocked.get(pid);
13780 }
13781 } catch (NumberFormatException e) {
13782 }
13783
13784 if (proc == null) {
13785 HashMap<String, SparseArray<ProcessRecord>> all
13786 = mProcessNames.getMap();
13787 SparseArray<ProcessRecord> procs = all.get(process);
13788 if (procs != null && procs.size() > 0) {
13789 proc = procs.valueAt(0);
13790 }
13791 }
13792
13793 if (proc == null || proc.thread == null) {
13794 throw new IllegalArgumentException("Unknown process: " + process);
13795 }
13796
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013797 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13798 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013799 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13800 throw new SecurityException("Process not debuggable: " + proc);
13801 }
13802 }
13803
13804 proc.thread.dumpHeap(managed, path, fd);
13805 fd = null;
13806 return true;
13807 }
13808 } catch (RemoteException e) {
13809 throw new IllegalStateException("Process disappeared");
13810 } finally {
13811 if (fd != null) {
13812 try {
13813 fd.close();
13814 } catch (IOException e) {
13815 }
13816 }
13817 }
13818 }
13819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013820 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13821 public void monitor() {
13822 synchronized (this) { }
13823 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013824
13825 public void onCoreSettingsChange(Bundle settings) {
13826 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13827 ProcessRecord processRecord = mLruProcesses.get(i);
13828 try {
13829 if (processRecord.thread != null) {
13830 processRecord.thread.setCoreSettings(settings);
13831 }
13832 } catch (RemoteException re) {
13833 /* ignore */
13834 }
13835 }
13836 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013837
13838 // Multi-user methods
13839
13840 public boolean switchUser(int userid) {
13841 // TODO
13842 return true;
13843 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013844}